Import Libraries¶

In [ ]:
from __future__ import division
from __future__ import print_function
from __future__ import absolute_import
import random
import pprint
import sys
import time
import numpy as np
import pickle
import math
import cv2
import copy
from matplotlib import pyplot as plt
import tensorflow as tf
import pandas as pd
import os

from sklearn.metrics import average_precision_score
from sklearn.metrics import confusion_matrix, roc_curve, auc
from sklearn.metrics import classification_report



import tensorflow as tf

from keras import backend as K
from keras.optimizers import Adam, SGD, RMSprop
from keras.layers import Layer, Flatten, Add, Dense, Input, InputSpec, Conv2D, Convolution2D, Activation, ZeroPadding2D, AveragePooling2D, MaxPooling2D, Dropout, TimeDistributed
from keras.losses import categorical_crossentropy

from keras.models import Model
from keras import initializers, regularizers

Config

In [ ]:
class Config:
	def __init__(self):

		self.verbose = True

		# Name of base network
		self.network = 'resnet'

		# Setting for data augmentation
		self.use_horizontal_flips = False
		self.use_vertical_flips = False
		self.rot_90 = False

		# Anchor box scales
    	# Note that if im_size is smaller, anchor_box_scales should be scaled
		self.anchor_box_scales = [128, 256, 512]

		# Anchor box ratios
		self.anchor_box_ratios = [[1, 1], [1./math.sqrt(2), 2./math.sqrt(2)], [2./math.sqrt(2), 1./math.sqrt(2)]]

		# Size to resize the smallest side of the image
		# Original setting in paper is 600. Set to 300 in here to save training time
		self.im_size = 640

		# image channel-wise mean to subtract
		self.img_channel_mean = [144.17631833, 144.17631833, 144.17631833]
		self.img_scaling_factor = 1.0

		# number of ROIs at once
		self.num_rois = 4

		# stride at the RPN (this depends on the network configuration)
		self.rpn_stride = 16

		self.balanced_classes = False

		# scaling the stdev
		self.std_scaling = 4.0
		self.classifier_regr_std = [8.0, 8.0, 4.0, 4.0]

		# overlaps for RPN
		self.rpn_min_overlap = 0.3
		self.rpn_max_overlap = 0.7

		# overlaps for classifier ROIs
		self.classifier_min_overlap = 0.1
		self.classifier_max_overlap = 0.5

		# Dataset path
		self.test_path = "dataset/test"

		# placeholder for the class mapping, automatically generated by the parser
		self.class_mapping = None

		self.record_path = "model/record_resnet_640_big_anchor.csv"
		self.model_path = "model/model_frcnn_resnet_640_big_anchor.h5"

		self.config_path = "config/config_resnet_640_big_anchor.pickle"
	

Parse data from annotation files

In [ ]:
def get_data(input_path, debug=False):
	"""Parse the data from annotation file
	
	Args:
		input_path: file path to folder containing annotation files

	Returns:
		all_data: list(filepath, width, height, list(bboxes))
		classes_count: dict{key:class_name, value:count_num}
		class_mapping: dict{key:class_name, value: idx}
		"""
	
	all_data = []
	classes_count = {}
	class_mapping = {"burr":0,"crack":1,"pit":2,"unpolished":3, "no_defect": 4}

	#image_blacklist = ["cast_def_0_3292","cast_def_0_3380","cast_def_0_937","cast_def_0_9276","cast_def_0_5214","cast_def_0_5205","cast_def_0_7994","cast_def_0_9079"]

	visualise = True

	print('Parsing annotation files')

	label_filenames = os.listdir( os.path.join(input_path, 'labels') )
	
	for filename in label_filenames:

		
		label_path = os.path.join(input_path,'labels', filename)

		# read the image
		img_path = os.path.join(input_path, 'images', filename.replace('txt', 'jpg'))
		img = cv2.imread(img_path)
		img_height, img_width, _ = img.shape

		data = {'img_path':img_path, 'label_path': label_path, 'width': img_width, 'height': img_height, 'bboxes': []}

		# flag to skip image from dataset
		skip = False
		with open(label_path, 'r') as f:

			for line in f.readlines():

				split = line.strip().split()
				class_id = int(split[0])

				x_center = float(split[1])
				y_center = float(split[2])
				width = float(split[3])
				height = float(split[4])

				# convert to (x1,y1,x2,y2) rectangle
				x1 = int((x_center - width/2) * img_width)
				y1 = int((y_center - height/2) * img_height)
				x2 = int((x_center + width/2) * img_width)
				y2 = int((y_center + height/2) * img_height)

				class_name = list(class_mapping.keys())[list(class_mapping.values()).index(class_id)]

				## CONSERTANDO ANOTAÇÕES QUE SAEM DA IMAGEM
				if class_name == "no_defect" and (x1 < 0 or y1 < 0 or x2 > img_width or y2 > img_height):
					if debug: print("No Defect Image out of bounds: ", img_path)
					if x1 < 0:
						x1 = 0
					if y1 < 0:
						y1 = 0
					if x2 > img_width:
						x2 = img_width
					if y2 > img_height:
						y2 = img_height
					if debug: print("Fixed: ", x1, y1, x2, y2)

				if class_name == "crack" and (x1 < 0 or y1 < 0 or x2 > img_width or y2 > img_height):
					if debug:
						print("Crack Image out of bounds: ", img_path)
						print("Skipping image")
					skip = True
				## FIM CONSERTANDO ANOTAÇÕES QUE SAEM DA IMAGEM

				data['bboxes'].append({'class': class_name, 'x1': x1, 'x2': x2, 'y1': y1, 'y2': y2})

				if not skip:
					if class_name not in classes_count:
						classes_count[class_name] = 1
					else:
						classes_count[class_name] += 1

		if not skip:
			all_data.append(data)

	return all_data, classes_count, class_mapping

Faster R-CNN Model¶

ROI Pooling Convolutional Layer

In [ ]:
class RoiPoolingConv(Layer):
    '''ROI pooling layer for 2D inputs.
    See Spatial Pyramid Pooling in Deep Convolutional Networks for Visual Recognition,
    K. He, X. Zhang, S. Ren, J. Sun
    # Arguments
        pool_size: int
            Size of pooling region to use. pool_size = 7 will result in a 7x7 region.
        num_rois: number of regions of interest to be used
    # Input shape
        list of two 4D tensors [X_img,X_roi] with shape:
        X_img:
        `(1, rows, cols, channels)`
        X_roi:
        `(1,num_rois,4)` list of rois, with ordering (x,y,w,h)
    # Output shape
        3D tensor with shape:
        `(1, num_rois, channels, pool_size, pool_size)`
    '''
    def __init__(self, pool_size, num_rois, **kwargs):

        self.dim_ordering = K.image_data_format()
        self.pool_size = pool_size
        self.num_rois = num_rois

        super(RoiPoolingConv, self).__init__(**kwargs)

    def build(self, input_shape):
        self.nb_channels = input_shape[0][3]   

    def compute_output_shape(self, input_shape):
        return None, self.num_rois, self.pool_size, self.pool_size, self.nb_channels

    def call(self, x, mask=None):

        assert(len(x) == 2)

        # x[0] is image with shape (rows, cols, channels)
        img = x[0]

        # x[1] is roi with shape (num_rois,4) with ordering (x,y,w,h)
        rois = x[1]

        input_shape = K.shape(img)

        outputs = []

        for roi_idx in range(self.num_rois):

            x = rois[0, roi_idx, 0]
            y = rois[0, roi_idx, 1]
            w = rois[0, roi_idx, 2]
            h = rois[0, roi_idx, 3]

            x = K.cast(x, 'int32')
            y = K.cast(y, 'int32')
            w = K.cast(w, 'int32')
            h = K.cast(h, 'int32')

            # Resized roi of the image to pooling size (7x7)
            rs = tf.image.resize(img[:, y:y+h, x:x+w, :], (self.pool_size, self.pool_size))
            outputs.append(rs)
                

        final_output = K.concatenate(outputs, axis=0)

        # Reshape to (1, num_rois, pool_size, pool_size, nb_channels)
        # Might be (1, 4, 7, 7, 3)
        final_output = K.reshape(final_output, (1, self.num_rois, self.pool_size, self.pool_size, self.nb_channels))

        # permute_dimensions is similar to transpose
        final_output = K.permute_dimensions(final_output, (0, 1, 2, 3, 4))

        return final_output
    
    
    def get_config(self):
        config = {'pool_size': self.pool_size,
                  'num_rois': self.num_rois}
        base_config = super(RoiPoolingConv, self).get_config()
        return dict(list(base_config.items()) + list(config.items()))

VGG-16

In [ ]:
def get_img_output_length(width, height):
    def get_output_length(input_length):
        return input_length//16

    return get_output_length(width), get_output_length(height)    

def nn_base(input_tensor=None, trainable=False):


    input_shape = (None, None, 3)

    if input_tensor is None:
        img_input = Input(shape=input_shape)
    else:
        if not K.is_keras_tensor(input_tensor):
            img_input = Input(tensor=input_tensor, shape=input_shape)
        else:
            img_input = input_tensor

    bn_axis = 3

    # Block 1
    x = Conv2D(64, (3, 3), activation='relu', padding='same', name='block1_conv1')(img_input)
    x = Conv2D(64, (3, 3), activation='relu', padding='same', name='block1_conv2')(x)
    x = MaxPooling2D((2, 2), strides=(2, 2), name='block1_pool')(x)

    # Block 2
    x = Conv2D(128, (3, 3), activation='relu', padding='same', name='block2_conv1')(x)
    x = Conv2D(128, (3, 3), activation='relu', padding='same', name='block2_conv2')(x)
    x = MaxPooling2D((2, 2), strides=(2, 2), name='block2_pool')(x)

    # Block 3
    x = Conv2D(256, (3, 3), activation='relu', padding='same', name='block3_conv1')(x)
    x = Conv2D(256, (3, 3), activation='relu', padding='same', name='block3_conv2')(x)
    x = Conv2D(256, (3, 3), activation='relu', padding='same', name='block3_conv3')(x)
    x = MaxPooling2D((2, 2), strides=(2, 2), name='block3_pool')(x)

    # Block 4
    x = Conv2D(512, (3, 3), activation='relu', padding='same', name='block4_conv1')(x)
    x = Conv2D(512, (3, 3), activation='relu', padding='same', name='block4_conv2')(x)
    x = Conv2D(512, (3, 3), activation='relu', padding='same', name='block4_conv3')(x)
    x = MaxPooling2D((2, 2), strides=(2, 2), name='block4_pool')(x)

    # Block 5
    x = Conv2D(512, (3, 3), activation='relu', padding='same', name='block5_conv1')(x)
    x = Conv2D(512, (3, 3), activation='relu', padding='same', name='block5_conv2')(x)
    x = Conv2D(512, (3, 3), activation='relu', padding='same', name='block5_conv3')(x)
    # x = MaxPooling2D((2, 2), strides=(2, 2), name='block5_pool')(x)

    return x

RPN Layer

In [ ]:
def rpn_layer(base_layers, num_anchors):
    """Create a rpn layer
        Step1: Pass through the feature map from base layer to a 3x3 512 channels convolutional layer
                Keep the padding 'same' to preserve the feature map's size
        Step2: Pass the step1 to two (1,1) convolutional layer to replace the fully connected layer
                classification layer: num_anchors (9 in here) channels for 0, 1 sigmoid activation output
                regression layer: num_anchors*4 (36 in here) channels for computing the regression of bboxes with linear activation
    Args:
        base_layers: vgg in here
        num_anchors: 9 in here

    Returns:
        [x_class, x_regr, base_layers]
        x_class: classification for whether it's an object
        x_regr: bboxes regression
        base_layers: vgg in here
    """
    x = Conv2D(512, (3, 3), padding='same', activation='relu', kernel_initializer='normal', name='rpn_conv1')(base_layers)

    x_class = Conv2D(num_anchors, (1, 1), activation='sigmoid', kernel_initializer='uniform', name='rpn_out_class')(x)
    x_regr = Conv2D(num_anchors * 4, (1, 1), activation='linear', kernel_initializer='zero', name='rpn_out_regress')(x)

    return [x_class, x_regr, base_layers]

Classifier Layer

In [ ]:
def classifier_layer(base_layers, input_rois, num_rois, nb_classes = 4, trainable=False):
    """Create a classifier layer
    
    Args:
        base_layers: vgg
        input_rois: `(1,num_rois,4)` list of rois, with ordering (x,y,w,h)
        num_rois: number of rois to be processed in one time (4 in here)

    Returns:
        list(out_class, out_regr)
        out_class: classifier layer output
        out_regr: regression layer output
    """

    input_shape = (num_rois,7,7,512)

    pooling_regions = 7

    # out_roi_pool.shape = (1, num_rois, channels, pool_size, pool_size)
    # num_rois (4) 7x7 roi pooling
    out_roi_pool = RoiPoolingConv(pooling_regions, num_rois)([base_layers, input_rois])

    # Flatten the convlutional layer and connected to 2 FC and 2 dropout
    out = TimeDistributed(Flatten(name='flatten'))(out_roi_pool)
    out = TimeDistributed(Dense(4096, activation='relu', name='fc1'))(out)
    out = TimeDistributed(Dropout(0.5))(out)
    out = TimeDistributed(Dense(4096, activation='relu', name='fc2'))(out)
    out = TimeDistributed(Dropout(0.5))(out)

    # There are two output layer
    # out_class: softmax acivation function for classify the class name of the object
    # out_regr: linear activation function for bboxes coordinates regression
    out_class = TimeDistributed(Dense(nb_classes, activation='softmax', kernel_initializer='zero'), name='dense_class_{}'.format(nb_classes))(out)
    # note: no regression target for bg class
    out_regr = TimeDistributed(Dense(4 * (nb_classes-1), activation='linear', kernel_initializer='zero'), name='dense_regress_{}'.format(nb_classes))(out)

    return [out_class, out_regr]

Resnet¶

In [ ]:
# Fixed Batch Normalization for Resnet

class FixedBatchNormalization(Layer):

    def __init__(self, epsilon=1e-3, axis=-1,
                 weights=None, beta_init='zero', gamma_init='one',
                 gamma_regularizer=None, beta_regularizer=None, **kwargs):

        self.supports_masking = True
        self.beta_init = initializers.get(beta_init)
        self.gamma_init = initializers.get(gamma_init)
        self.epsilon = epsilon
        self.axis = axis
        self.gamma_regularizer = regularizers.get(gamma_regularizer)
        self.beta_regularizer = regularizers.get(beta_regularizer)
        self.initial_weights = weights
        super(FixedBatchNormalization, self).__init__(**kwargs)

    def build(self, input_shape):
        self.input_spec = [InputSpec(shape=input_shape)]
        shape = (input_shape[self.axis],)

        self.gamma = self.add_weight(shape=shape,
                                     initializer=self.gamma_init,
                                     regularizer=self.gamma_regularizer,
                                     name='{}_gamma'.format(self.name),
                                     trainable=False)
        self.beta = self.add_weight(shape=shape,
                                    initializer=self.beta_init,
                                    regularizer=self.beta_regularizer,
                                    name='{}_beta'.format(self.name),
                                    trainable=False)
        self.running_mean = self.add_weight(shape=shape, initializer='zero',
                                            name='{}_running_mean'.format(self.name),
                                            trainable=False)
        self.running_std = self.add_weight(shape=shape, initializer='one',
                                           name='{}_running_std'.format(self.name),
                                           trainable=False)

        if self.initial_weights is not None:
            self.set_weights(self.initial_weights)
            del self.initial_weights

        self.built = True

    def call(self, x, mask=None):

        assert self.built, 'Layer must be built before being called'
        input_shape = K.int_shape(x)

        reduction_axes = list(range(len(input_shape)))
        del reduction_axes[self.axis]
        broadcast_shape = [1] * len(input_shape)
        broadcast_shape[self.axis] = input_shape[self.axis]

        if sorted(reduction_axes) == range(K.ndim(x))[:-1]:
            x_normed = K.batch_normalization(
                x, self.running_mean, self.running_std,
                self.beta, self.gamma,
                epsilon=self.epsilon)
        else:
            # need broadcasting
            broadcast_running_mean = K.reshape(self.running_mean, broadcast_shape)
            broadcast_running_std = K.reshape(self.running_std, broadcast_shape)
            broadcast_beta = K.reshape(self.beta, broadcast_shape)
            broadcast_gamma = K.reshape(self.gamma, broadcast_shape)
            x_normed = K.batch_normalization(
                x, broadcast_running_mean, broadcast_running_std,
                broadcast_beta, broadcast_gamma,
                epsilon=self.epsilon)

        return x_normed

    def get_config(self):
        config = {'epsilon': self.epsilon,
                  'axis': self.axis,
                  'gamma_regularizer': self.gamma_regularizer.get_config() if self.gamma_regularizer else None,
                  'beta_regularizer': self.beta_regularizer.get_config() if self.beta_regularizer else None}
        base_config = super(FixedBatchNormalization, self).get_config()
        return dict(list(base_config.items()) + list(config.items()))
In [ ]:
def get_img_output_length_resnet(width, height):
    def get_output_length(input_length):
        # zero_pad
        input_length += 6
        # apply 4 strided convolutions
        filter_sizes = [7, 3, 1, 1]
        stride = 2
        for filter_size in filter_sizes:
            input_length = (input_length - filter_size + stride) // stride
        return input_length

    return get_output_length(width), get_output_length(height) 

def identity_block(input_tensor, kernel_size, filters, stage, block, trainable=True):

    nb_filter1, nb_filter2, nb_filter3 = filters
    
    bn_axis = 3


    conv_name_base = 'res' + str(stage) + block + '_branch'
    bn_name_base = 'bn' + str(stage) + block + '_branch'

    x = Convolution2D(nb_filter1, (1, 1), name=conv_name_base + '2a', trainable=trainable)(input_tensor)
    x = FixedBatchNormalization(axis=bn_axis, name=bn_name_base + '2a')(x)
    x = Activation('relu')(x)

    x = Convolution2D(nb_filter2, (kernel_size, kernel_size), padding='same', name=conv_name_base + '2b', trainable=trainable)(x)
    x = FixedBatchNormalization(axis=bn_axis, name=bn_name_base + '2b')(x)
    x = Activation('relu')(x)

    x = Convolution2D(nb_filter3, (1, 1), name=conv_name_base + '2c', trainable=trainable)(x)
    x = FixedBatchNormalization(axis=bn_axis, name=bn_name_base + '2c')(x)

    x = Add()([x, input_tensor])
    x = Activation('relu')(x)
    return x


def identity_block_td(input_tensor, kernel_size, filters, stage, block, trainable=True):

    # identity block time distributed

    nb_filter1, nb_filter2, nb_filter3 = filters

    bn_axis = 3

    conv_name_base = 'res' + str(stage) + block + '_branch'
    bn_name_base = 'bn' + str(stage) + block + '_branch'

    x = TimeDistributed(Convolution2D(nb_filter1, (1, 1), trainable=trainable, kernel_initializer='normal'), name=conv_name_base + '2a')(input_tensor)
    x = TimeDistributed(FixedBatchNormalization(axis=bn_axis), name=bn_name_base + '2a')(x)
    x = Activation('relu')(x)

    x = TimeDistributed(Convolution2D(nb_filter2, (kernel_size, kernel_size), trainable=trainable, kernel_initializer='normal',padding='same'), name=conv_name_base + '2b')(x)
    x = TimeDistributed(FixedBatchNormalization(axis=bn_axis), name=bn_name_base + '2b')(x)
    x = Activation('relu')(x)

    x = TimeDistributed(Convolution2D(nb_filter3, (1, 1), trainable=trainable, kernel_initializer='normal'), name=conv_name_base + '2c')(x)
    x = TimeDistributed(FixedBatchNormalization(axis=bn_axis), name=bn_name_base + '2c')(x)

    x = Add()([x, input_tensor])
    x = Activation('relu')(x)

    return x

def conv_block(input_tensor, kernel_size, filters, stage, block, strides=(2, 2), trainable=True):

    nb_filter1, nb_filter2, nb_filter3 = filters
    bn_axis = 3
    
    conv_name_base = 'res' + str(stage) + block + '_branch'
    bn_name_base = 'bn' + str(stage) + block + '_branch'

    x = Convolution2D(nb_filter1, (1, 1), strides=strides, name=conv_name_base + '2a', trainable=trainable)(input_tensor)
    x = FixedBatchNormalization(axis=bn_axis, name=bn_name_base + '2a')(x)
    x = Activation('relu')(x)

    x = Convolution2D(nb_filter2, (kernel_size, kernel_size), padding='same', name=conv_name_base + '2b', trainable=trainable)(x)
    x = FixedBatchNormalization(axis=bn_axis, name=bn_name_base + '2b')(x)
    x = Activation('relu')(x)

    x = Convolution2D(nb_filter3, (1, 1), name=conv_name_base + '2c', trainable=trainable)(x)
    x = FixedBatchNormalization(axis=bn_axis, name=bn_name_base + '2c')(x)

    shortcut = Convolution2D(nb_filter3, (1, 1), strides=strides, name=conv_name_base + '1', trainable=trainable)(input_tensor)
    shortcut = FixedBatchNormalization(axis=bn_axis, name=bn_name_base + '1')(shortcut)

    x = Add()([x, shortcut])
    x = Activation('relu')(x)
    return x


def conv_block_td(input_tensor, kernel_size, filters, stage, block, input_shape, strides=(2, 2), trainable=True):

    # conv block time distributed

    nb_filter1, nb_filter2, nb_filter3 = filters

    bn_axis = 3


    conv_name_base = 'res' + str(stage) + block + '_branch'
    bn_name_base = 'bn' + str(stage) + block + '_branch'

    x = TimeDistributed(Convolution2D(nb_filter1, (1, 1), strides=strides, trainable=trainable, kernel_initializer='normal'), input_shape=input_shape, name=conv_name_base + '2a')(input_tensor)
    x = TimeDistributed(FixedBatchNormalization(axis=bn_axis), name=bn_name_base + '2a')(x)
    x = Activation('relu')(x)

    x = TimeDistributed(Convolution2D(nb_filter2, (kernel_size, kernel_size), padding='same', trainable=trainable, kernel_initializer='normal'), name=conv_name_base + '2b')(x)
    x = TimeDistributed(FixedBatchNormalization(axis=bn_axis), name=bn_name_base + '2b')(x)
    x = Activation('relu')(x)

    x = TimeDistributed(Convolution2D(nb_filter3, (1, 1), kernel_initializer='normal'), name=conv_name_base + '2c', trainable=trainable)(x)
    x = TimeDistributed(FixedBatchNormalization(axis=bn_axis), name=bn_name_base + '2c')(x)

    shortcut = TimeDistributed(Convolution2D(nb_filter3, (1, 1), strides=strides, trainable=trainable, kernel_initializer='normal'), name=conv_name_base + '1')(input_tensor)
    shortcut = TimeDistributed(FixedBatchNormalization(axis=bn_axis), name=bn_name_base + '1')(shortcut)

    x = Add()([x, shortcut])
    x = Activation('relu')(x)
    return x

def nn_base_resnet(input_tensor=None, trainable=False):
   
    input_shape = (None, None, 3)

    if input_tensor is None:
        img_input = Input(shape=input_shape)
    else:
        if not K.is_keras_tensor(input_tensor):
            img_input = Input(tensor=input_tensor, shape=input_shape)
        else:
            img_input = input_tensor

    bn_axis = 3
    
    x = ZeroPadding2D((3, 3))(img_input)

    x = Convolution2D(64, (7, 7), strides=(2, 2), name='conv1', trainable = trainable)(x)
    x = FixedBatchNormalization(axis=bn_axis, name='bn_conv1')(x)
    x = Activation('relu')(x)
    x = MaxPooling2D((3, 3), strides=(2, 2))(x)

    x = conv_block(x, 3, [64, 64, 256], stage=2, block='a', strides=(1, 1), trainable = trainable)
    x = identity_block(x, 3, [64, 64, 256], stage=2, block='b', trainable = trainable)
    x = identity_block(x, 3, [64, 64, 256], stage=2, block='c', trainable = trainable)

    x = conv_block(x, 3, [128, 128, 512], stage=3, block='a', trainable = trainable)
    x = identity_block(x, 3, [128, 128, 512], stage=3, block='b', trainable = trainable)
    x = identity_block(x, 3, [128, 128, 512], stage=3, block='c', trainable = trainable)
    x = identity_block(x, 3, [128, 128, 512], stage=3, block='d', trainable = trainable)

    x = conv_block(x, 3, [256, 256, 1024], stage=4, block='a', trainable = trainable)
    x = identity_block(x, 3, [256, 256, 1024], stage=4, block='b', trainable = trainable)
    x = identity_block(x, 3, [256, 256, 1024], stage=4, block='c', trainable = trainable)
    x = identity_block(x, 3, [256, 256, 1024], stage=4, block='d', trainable = trainable)
    x = identity_block(x, 3, [256, 256, 1024], stage=4, block='e', trainable = trainable)
    x = identity_block(x, 3, [256, 256, 1024], stage=4, block='f', trainable = trainable)

    return x


def classifier_layers_resnet(x, input_shape, trainable=False):

    # compile times on theano tend to be very high, so we use smaller ROI pooling regions to workaround
    # (hence a smaller stride in the region that follows the ROI pool)
    x = conv_block_td(x, 3, [512, 512, 2048], stage=5, block='a', input_shape=input_shape, strides=(2, 2), trainable=trainable)

    x = identity_block_td(x, 3, [512, 512, 2048], stage=5, block='b', trainable=trainable)
    x = identity_block_td(x, 3, [512, 512, 2048], stage=5, block='c', trainable=trainable)
    x = TimeDistributed(AveragePooling2D((7, 7)), name='avg_pool')(x)

    return x


def rpn_resnet(base_layers,num_anchors):

    x = Convolution2D(512, (3, 3), padding='same', activation='relu', kernel_initializer='normal', name='rpn_conv1')(base_layers)

    x_class = Convolution2D(num_anchors, (1, 1), activation='sigmoid', kernel_initializer='uniform', name='rpn_out_class')(x)
    x_regr = Convolution2D(num_anchors * 4, (1, 1), activation='linear', kernel_initializer='zero', name='rpn_out_regress')(x)

    return [x_class, x_regr, base_layers]

def classifier_resnet(base_layers, input_rois, num_rois, nb_classes = 6, trainable=False):

    pooling_regions = 14
    input_shape = (num_rois,14,14,1024)

    out_roi_pool = RoiPoolingConv(pooling_regions, num_rois)([base_layers, input_rois])
    print("Roi pool shape: ", out_roi_pool.shape)
    out = classifier_layers_resnet(out_roi_pool, input_shape=input_shape, trainable=True)

    out = TimeDistributed(Flatten())(out)

    out_class = TimeDistributed(Dense(nb_classes, activation='softmax', kernel_initializer='zero'), name='dense_class_{}'.format(nb_classes))(out)
    # note: no regression target for bg class
    out_regr = TimeDistributed(Dense(4 * (nb_classes-1), activation='linear', kernel_initializer='zero'), name='dense_regress_{}'.format(nb_classes))(out)
    return [out_class, out_regr]

Calculate Intersection over Union (IoU)¶

In [ ]:
def union(au, bu, area_intersection):
	area_a = (au[2] - au[0]) * (au[3] - au[1])
	area_b = (bu[2] - bu[0]) * (bu[3] - bu[1])
	area_union = area_a + area_b - area_intersection
	return area_union


def intersection(ai, bi):
	x = max(ai[0], bi[0])
	y = max(ai[1], bi[1])
	w = min(ai[2], bi[2]) - x
	h = min(ai[3], bi[3]) - y
	if w < 0 or h < 0:
		return 0
	return w*h


def iou(a, b):
	# a and b should be (x1,y1,x2,y2)

	if a[0] >= a[2] or a[1] >= a[3] or b[0] >= b[2] or b[1] >= b[3]:
		return 0.0

	area_i = intersection(a, b)
	area_u = union(a, b, area_i)

	return float(area_i) / float(area_u + 1e-6)

Calculate RPN for all anchors of all images

In [ ]:
def calc_rpn(C, img_data, width, height, resized_width, resized_height, img_length_calc_function):
	"""(Important part!) Calculate the rpn for all anchors 
		If feature map has shape 38x50=1900, there are 1900x9=17100 potential anchors
	
	Args:
		C: config
		img_data: augmented image data
		width: original image width (e.g. 600)
		height: original image height (e.g. 800)
		resized_width: resized image width according to C.im_size (e.g. 300)
		resized_height: resized image height according to C.im_size (e.g. 400)
		img_length_calc_function: function to calculate final layer's feature map (of base model) size according to input image size

	Returns:
		y_rpn_cls: list(num_bboxes, y_is_box_valid + y_rpn_overlap)
			y_is_box_valid: 0 or 1 (0 means the box is invalid, 1 means the box is valid)
			y_rpn_overlap: 0 or 1 (0 means the box is not an object, 1 means the box is an object)
		y_rpn_regr: list(num_bboxes, 4*y_rpn_overlap + y_rpn_regr)
			y_rpn_regr: x1,y1,x2,y2 bunding boxes coordinates
	"""
	downscale = float(C.rpn_stride) 
	anchor_sizes = C.anchor_box_scales   # 128, 256, 512
	anchor_ratios = C.anchor_box_ratios  # 1:1, 1:2*sqrt(2), 2*sqrt(2):1
	num_anchors = len(anchor_sizes) * len(anchor_ratios) # 3x3=9

	# calculate the output map size based on the network architecture
	(output_width, output_height) = img_length_calc_function(resized_width, resized_height)

	n_anchratios = len(anchor_ratios)    # 3
	
	# initialise empty output objectives
	y_rpn_overlap = np.zeros((output_height, output_width, num_anchors))
	y_is_box_valid = np.zeros((output_height, output_width, num_anchors))
	y_rpn_regr = np.zeros((output_height, output_width, num_anchors * 4))

	num_bboxes = len(img_data['bboxes'])

	num_anchors_for_bbox = np.zeros(num_bboxes).astype(int)
	best_anchor_for_bbox = -1*np.ones((num_bboxes, 4)).astype(int)
	best_iou_for_bbox = np.zeros(num_bboxes).astype(np.float32)
	best_x_for_bbox = np.zeros((num_bboxes, 4)).astype(int)
	best_dx_for_bbox = np.zeros((num_bboxes, 4)).astype(np.float32)

	# get the GT box coordinates, and resize to account for image resizing
	gta = np.zeros((num_bboxes, 4))
	for bbox_num, bbox in enumerate(img_data['bboxes']):
		# get the GT box coordinates, and resize to account for image resizing
		gta[bbox_num, 0] = bbox['x1'] * (resized_width / float(width))
		gta[bbox_num, 1] = bbox['x2'] * (resized_width / float(width))
		gta[bbox_num, 2] = bbox['y1'] * (resized_height / float(height))
		gta[bbox_num, 3] = bbox['y2'] * (resized_height / float(height))
	
	# rpn ground truth

	for anchor_size_idx in range(len(anchor_sizes)):
		for anchor_ratio_idx in range(n_anchratios):
			anchor_x = anchor_sizes[anchor_size_idx] * anchor_ratios[anchor_ratio_idx][0]
			anchor_y = anchor_sizes[anchor_size_idx] * anchor_ratios[anchor_ratio_idx][1]	
			
			for ix in range(output_width):					
				# x-coordinates of the current anchor box	
				x1_anc = downscale * (ix + 0.5) - anchor_x / 2
				x2_anc = downscale * (ix + 0.5) + anchor_x / 2	
				
				# ignore boxes that go across image boundaries					
				if x1_anc < 0 or x2_anc > resized_width:
					continue
					
				for jy in range(output_height):

					# y-coordinates of the current anchor box
					y1_anc = downscale * (jy + 0.5) - anchor_y / 2
					y2_anc = downscale * (jy + 0.5) + anchor_y / 2

					# ignore boxes that go across image boundaries
					if y1_anc < 0 or y2_anc > resized_height:
						continue

					# bbox_type indicates whether an anchor should be a target
					# Initialize with 'negative'
					bbox_type = 'neg'

					# this is the best IOU for the (x,y) coord and the current anchor
					# note that this is different from the best IOU for a GT bbox
					best_iou_for_loc = 0.0

					for bbox_num in range(num_bboxes):
						
						# get IOU of the current GT box and the current anchor box
						curr_iou = iou([gta[bbox_num, 0], gta[bbox_num, 2], gta[bbox_num, 1], gta[bbox_num, 3]], [x1_anc, y1_anc, x2_anc, y2_anc])
						# calculate the regression targets if they will be needed
						if curr_iou > best_iou_for_bbox[bbox_num] or curr_iou > C.rpn_max_overlap:
							cx = (gta[bbox_num, 0] + gta[bbox_num, 1]) / 2.0
							cy = (gta[bbox_num, 2] + gta[bbox_num, 3]) / 2.0
							cxa = (x1_anc + x2_anc)/2.0
							cya = (y1_anc + y2_anc)/2.0

							# x,y are the center point of ground-truth bbox
							# xa,ya are the center point of anchor bbox (xa=downscale * (ix + 0.5); ya=downscale * (iy+0.5))
							# w,h are the width and height of ground-truth bbox
							# wa,ha are the width and height of anchor bboxe
							# tx = (x - xa) / wa
							# ty = (y - ya) / ha
							# tw = log(w / wa)
							# th = log(h / ha)
							tx = (cx - cxa) / (x2_anc - x1_anc)
							ty = (cy - cya) / (y2_anc - y1_anc)
							tw = np.log((gta[bbox_num, 1] - gta[bbox_num, 0]) / (x2_anc - x1_anc))
							th = np.log((gta[bbox_num, 3] - gta[bbox_num, 2]) / (y2_anc - y1_anc))
						
						if img_data['bboxes'][bbox_num]['class'] != 'bg':

							# all GT boxes should be mapped to an anchor box, so we keep track of which anchor box was best
							if curr_iou > best_iou_for_bbox[bbox_num]:
								best_anchor_for_bbox[bbox_num] = [jy, ix, anchor_ratio_idx, anchor_size_idx]
								best_iou_for_bbox[bbox_num] = curr_iou
								best_x_for_bbox[bbox_num,:] = [x1_anc, x2_anc, y1_anc, y2_anc]
								best_dx_for_bbox[bbox_num,:] = [tx, ty, tw, th]

							# we set the anchor to positive if the IOU is >0.7 (it does not matter if there was another better box, it just indicates overlap)
							if curr_iou > C.rpn_max_overlap:
								bbox_type = 'pos'
								num_anchors_for_bbox[bbox_num] += 1
								# we update the regression layer target if this IOU is the best for the current (x,y) and anchor position
								if curr_iou > best_iou_for_loc:
									best_iou_for_loc = curr_iou
									best_regr = (tx, ty, tw, th)

							# if the IOU is >0.3 and <0.7, it is ambiguous and no included in the objective
							if C.rpn_min_overlap < curr_iou < C.rpn_max_overlap:
								# gray zone between neg and pos
								if bbox_type != 'pos':
									bbox_type = 'neutral'

					# turn on or off outputs depending on IOUs
					if bbox_type == 'neg':
						y_is_box_valid[jy, ix, anchor_ratio_idx + n_anchratios * anchor_size_idx] = 1
						y_rpn_overlap[jy, ix, anchor_ratio_idx + n_anchratios * anchor_size_idx] = 0
					elif bbox_type == 'neutral':
						y_is_box_valid[jy, ix, anchor_ratio_idx + n_anchratios * anchor_size_idx] = 0
						y_rpn_overlap[jy, ix, anchor_ratio_idx + n_anchratios * anchor_size_idx] = 0
					elif bbox_type == 'pos':
						y_is_box_valid[jy, ix, anchor_ratio_idx + n_anchratios * anchor_size_idx] = 1
						y_rpn_overlap[jy, ix, anchor_ratio_idx + n_anchratios * anchor_size_idx] = 1
						start = 4 * (anchor_ratio_idx + n_anchratios * anchor_size_idx)
						y_rpn_regr[jy, ix, start:start+4] = best_regr

	# we ensure that every bbox has at least one positive RPN region

	for idx in range(num_anchors_for_bbox.shape[0]):
		if num_anchors_for_bbox[idx] == 0:
			# no box with an IOU greater than zero ...
			if best_anchor_for_bbox[idx, 0] == -1:
				continue
			y_is_box_valid[
				best_anchor_for_bbox[idx,0], best_anchor_for_bbox[idx,1], best_anchor_for_bbox[idx,2] + n_anchratios *
				best_anchor_for_bbox[idx,3]] = 1
			y_rpn_overlap[
				best_anchor_for_bbox[idx,0], best_anchor_for_bbox[idx,1], best_anchor_for_bbox[idx,2] + n_anchratios *
				best_anchor_for_bbox[idx,3]] = 1
			start = 4 * (best_anchor_for_bbox[idx,2] + n_anchratios * best_anchor_for_bbox[idx,3])
			y_rpn_regr[
				best_anchor_for_bbox[idx,0], best_anchor_for_bbox[idx,1], start:start+4] = best_dx_for_bbox[idx, :]

	y_rpn_overlap = np.transpose(y_rpn_overlap, (2, 0, 1))
	y_rpn_overlap = np.expand_dims(y_rpn_overlap, axis=0)

	y_is_box_valid = np.transpose(y_is_box_valid, (2, 0, 1))
	y_is_box_valid = np.expand_dims(y_is_box_valid, axis=0)

	y_rpn_regr = np.transpose(y_rpn_regr, (2, 0, 1))
	y_rpn_regr = np.expand_dims(y_rpn_regr, axis=0)

	pos_locs = np.where(np.logical_and(y_rpn_overlap[0, :, :, :] == 1, y_is_box_valid[0, :, :, :] == 1))
	neg_locs = np.where(np.logical_and(y_rpn_overlap[0, :, :, :] == 0, y_is_box_valid[0, :, :, :] == 1))

	num_pos = len(pos_locs[0])

	# one issue is that the RPN has many more negative than positive regions, so we turn off some of the negative
	# regions. We also limit it to 256 regions.
	num_regions = 256

	if len(pos_locs[0]) > num_regions/2:
		val_locs = random.sample(range(len(pos_locs[0])), len(pos_locs[0]) - num_regions/2)
		y_is_box_valid[0, pos_locs[0][val_locs], pos_locs[1][val_locs], pos_locs[2][val_locs]] = 0
		num_pos = num_regions/2

	if len(neg_locs[0]) + num_pos > num_regions:
		val_locs = random.sample(range(len(neg_locs[0])), len(neg_locs[0]) - num_pos)
		y_is_box_valid[0, neg_locs[0][val_locs], neg_locs[1][val_locs], neg_locs[2][val_locs]] = 0

	y_rpn_cls = np.concatenate([y_is_box_valid, y_rpn_overlap], axis=1)
	y_rpn_regr = np.concatenate([np.repeat(y_rpn_overlap, 4, axis=1), y_rpn_regr], axis=1)

	return np.copy(y_rpn_cls), np.copy(y_rpn_regr), num_pos

Augmentation

In [ ]:
def get_new_img_size(width, height, img_min_side=640):
	if width <= height:
		f = float(img_min_side) / width
		resized_height = int(f * height)
		resized_width = img_min_side
	else:
		f = float(img_min_side) / height
		resized_width = int(f * width)
		resized_height = img_min_side

	return resized_width, resized_height

def augment(img_data, config, augment=True):
	assert 'img_path' in img_data
	assert 'label_path' in img_data
	assert 'bboxes' in img_data
	assert 'width' in img_data
	assert 'height' in img_data

	img_data_aug = copy.deepcopy(img_data)

	img = cv2.imread(img_data_aug['img_path'])

	if augment:
		rows, cols = img.shape[:2]

		if config.use_horizontal_flips and np.random.randint(0, 2) == 0:
			img = cv2.flip(img, 1)
			for bbox in img_data_aug['bboxes']:
				x1 = bbox['x1']
				x2 = bbox['x2']
				bbox['x2'] = cols - x1
				bbox['x1'] = cols - x2

		if config.use_vertical_flips and np.random.randint(0, 2) == 0:
			img = cv2.flip(img, 0)
			for bbox in img_data_aug['bboxes']:
				y1 = bbox['y1']
				y2 = bbox['y2']
				bbox['y2'] = rows - y1
				bbox['y1'] = rows - y2

		if config.rot_90:
			angle = np.random.choice([0,90,180,270],1)[0]
			if angle == 270:
				img = np.transpose(img, (1,0,2))
				img = cv2.flip(img, 0)
			elif angle == 180:
				img = cv2.flip(img, -1)
			elif angle == 90:
				img = np.transpose(img, (1,0,2))
				img = cv2.flip(img, 1)
			elif angle == 0:
				pass

			for bbox in img_data_aug['bboxes']:
				x1 = bbox['x1']
				x2 = bbox['x2']
				y1 = bbox['y1']
				y2 = bbox['y2']
				if angle == 270:
					bbox['x1'] = y1
					bbox['x2'] = y2
					bbox['y1'] = cols - x2
					bbox['y2'] = cols - x1
				elif angle == 180:
					bbox['x2'] = cols - x1
					bbox['x1'] = cols - x2
					bbox['y2'] = rows - y1
					bbox['y1'] = rows - y2
				elif angle == 90:
					bbox['x1'] = rows - y2
					bbox['x2'] = rows - y1
					bbox['y1'] = x1
					bbox['y2'] = x2        
				elif angle == 0:
					pass

	img_data_aug['width'] = img.shape[1]
	img_data_aug['height'] = img.shape[0]
	return img_data_aug, img

Generate "Ground Truth" Anchors

In [ ]:
def get_anchor_gt(all_img_data, C, img_length_calc_function, mode='train'):
	""" Yield the ground-truth anchors as Y (labels)
		
	Args:
		all_img_data: list(filepath, width, height, list(bboxes))
		C: config
		img_length_calc_function: function to calculate final layer's feature map (of base model) size according to input image size
		mode: 'train' or 'test'; 'train' mode need augmentation

	Returns:
		x_img: image data after resized and scaling (smallest size = 300px)
		Y: [y_rpn_cls, y_rpn_regr]
		img_data_aug: augmented image data (original image with augmentation)
		debug_img: show image for debug
		num_pos: show number of positive anchors for debug
	"""
	while True:

		for img_data in all_img_data:
			try:

				# read in image, and optionally add augmentation

				if mode == 'train':
					img_data_aug, x_img = augment(img_data, C, augment=True)
				else:
					img_data_aug, x_img = augment(img_data, C, augment=False)

				(width, height) = (img_data_aug['width'], img_data_aug['height'])
				(rows, cols, _) = x_img.shape

				assert cols == width
				assert rows == height

				# get image dimensions for resizing
				(resized_width, resized_height) = get_new_img_size(width, height, C.im_size)

				# resize the image so that smalles side is length = 300px
				x_img = cv2.resize(x_img, (resized_width, resized_height), interpolation=cv2.INTER_CUBIC)
				debug_img = x_img.copy()

				try:
					y_rpn_cls, y_rpn_regr, num_pos = calc_rpn(C, img_data_aug, width, height, resized_width, resized_height, img_length_calc_function)
				except:
					continue

				# Zero-center by mean pixel, and preprocess image

				x_img = x_img[:,:, (2, 1, 0)]  # BGR -> RGB
				x_img = x_img.astype(np.float32)
				x_img[:, :, 0] -= C.img_channel_mean[0]
				x_img[:, :, 1] -= C.img_channel_mean[1]
				x_img[:, :, 2] -= C.img_channel_mean[2]
				x_img /= C.img_scaling_factor

				x_img = np.transpose(x_img, (2, 0, 1))
				x_img = np.expand_dims(x_img, axis=0)

				y_rpn_regr[:, y_rpn_regr.shape[1]//2:, :, :] *= C.std_scaling

				x_img = np.transpose(x_img, (0, 2, 3, 1))
				y_rpn_cls = np.transpose(y_rpn_cls, (0, 2, 3, 1))
				y_rpn_regr = np.transpose(y_rpn_regr, (0, 2, 3, 1))

				###
				# x_img convert to int32
				# x_img = np.around(x_img)
				###

				yield np.copy(x_img), [np.copy(y_rpn_cls), np.copy(y_rpn_regr)], img_data_aug, debug_img, num_pos

			except Exception as e:
				print(e)
				continue

Define loss functions for all four outputs

In [ ]:
lambda_rpn_regr = 1.0
lambda_rpn_class = 1.0

lambda_cls_regr = 1.0
lambda_cls_class = 1.0

epsilon = 1e-4
In [ ]:
def rpn_loss_regr(num_anchors):
    """Loss function for rpn regression
    Args:
        num_anchors: number of anchors (9 in here)
    Returns:
        Smooth L1 loss function 
                           0.5*x*x (if x_abs < 1)
                           x_abx - 0.5 (otherwise)
    """
    def rpn_loss_regr_fixed_num(y_true, y_pred):

        # x is the difference between true value and predicted vaue
        x = y_true[:, :, :, 4 * num_anchors:] - y_pred

        # absolute value of x
        x_abs = K.abs(x)

        # If x_abs <= 1.0, x_bool = 1
        x_bool = K.cast(K.less_equal(x_abs, 1.0), tf.float32)

        return lambda_rpn_regr * K.sum(
            y_true[:, :, :, :4 * num_anchors] * (x_bool * (0.5 * x * x) + (1 - x_bool) * (x_abs - 0.5))) / K.sum(epsilon + y_true[:, :, :, :4 * num_anchors])

    return rpn_loss_regr_fixed_num


def rpn_loss_cls(num_anchors):
    """Loss function for rpn classification
    Args:
        num_anchors: number of anchors (9 in here)
        y_true[:, :, :, :9]: [0,1,0,0,0,0,0,1,0] means only the second and the eighth box is valid which contains pos or neg anchor => isValid
        y_true[:, :, :, 9:]: [0,1,0,0,0,0,0,0,0] means the second box is pos and eighth box is negative
    Returns:
        lambda * sum((binary_crossentropy(isValid*y_pred,y_true))) / N
    """
    def rpn_loss_cls_fixed_num(y_true, y_pred):

            return lambda_rpn_class * K.sum(y_true[:, :, :, :num_anchors] * K.binary_crossentropy(y_pred[:, :, :, :], y_true[:, :, :, num_anchors:])) / K.sum(epsilon + y_true[:, :, :, :num_anchors])

    return rpn_loss_cls_fixed_num


def class_loss_regr(num_classes):
    """Loss function for rpn regression
    Args:
        num_anchors: number of anchors (9 in here)
    Returns:
        Smooth L1 loss function 
                           0.5*x*x (if x_abs < 1)
                           x_abx - 0.5 (otherwise)
    """
    def class_loss_regr_fixed_num(y_true, y_pred):
        x = y_true[:, :, 4*num_classes:] - y_pred
        x_abs = K.abs(x)
        x_bool = K.cast(K.less_equal(x_abs, 1.0), 'float32')
        return lambda_cls_regr * K.sum(y_true[:, :, :4*num_classes] * (x_bool * (0.5 * x * x) + (1 - x_bool) * (x_abs - 0.5))) / K.sum(epsilon + y_true[:, :, :4*num_classes])
    return class_loss_regr_fixed_num


def class_loss_cls(y_true, y_pred):
    return lambda_cls_class * K.mean(categorical_crossentropy(y_true[0, :, :], y_pred[0, :, :]))

Non Max Suppression

In [ ]:
def non_max_suppression_fast(boxes, probs, overlap_thresh=0.9, max_boxes=300):
    # code used from here: http://www.pyimagesearch.com/2015/02/16/faster-non-maximum-suppression-python/
    # if there are no boxes, return an empty list

    # Process explanation:
    #   Step 1: Sort the probs list
    #   Step 2: Find the larget prob 'Last' in the list and save it to the pick list
    #   Step 3: Calculate the IoU with 'Last' box and other boxes in the list. If the IoU is larger than overlap_threshold, delete the box from list
    #   Step 4: Repeat step 2 and step 3 until there is no item in the probs list 
    if len(boxes) == 0:
        return []

    # grab the coordinates of the bounding boxes
    x1 = boxes[:, 0]
    y1 = boxes[:, 1]
    x2 = boxes[:, 2]
    y2 = boxes[:, 3]

    np.testing.assert_array_less(x1, x2)
    np.testing.assert_array_less(y1, y2)

    # if the bounding boxes integers, convert them to floats --
    # this is important since we'll be doing a bunch of divisions
    if boxes.dtype.kind == "i":
        boxes = boxes.astype("float")

    # initialize the list of picked indexes	
    pick = []

    # calculate the areas
    area = (x2 - x1) * (y2 - y1)

    # sort the bounding boxes 
    idxs = np.argsort(probs)

    # keep looping while some indexes still remain in the indexes
    # list
    while len(idxs) > 0:
        # grab the last index in the indexes list and add the
        # index value to the list of picked indexes
        last = len(idxs) - 1
        i = idxs[last]
        pick.append(i)

        # find the intersection

        xx1_int = np.maximum(x1[i], x1[idxs[:last]])
        yy1_int = np.maximum(y1[i], y1[idxs[:last]])
        xx2_int = np.minimum(x2[i], x2[idxs[:last]])
        yy2_int = np.minimum(y2[i], y2[idxs[:last]])

        ww_int = np.maximum(0, xx2_int - xx1_int)
        hh_int = np.maximum(0, yy2_int - yy1_int)

        area_int = ww_int * hh_int

        # find the union
        area_union = area[i] + area[idxs[:last]] - area_int

        # compute the ratio of overlap
        overlap = area_int/(area_union + 1e-6)

        # delete all indexes from the index list that have
        idxs = np.delete(idxs, np.concatenate(([last],
            np.where(overlap > overlap_thresh)[0])))

        if len(pick) >= max_boxes:
            break

    # return only the bounding boxes that were picked using the integer data type
    boxes = boxes[pick].astype("int")
    probs = probs[pick]
    return boxes, probs

def apply_regr_np(X, T):
    """Apply regression layer to all anchors in one feature map

    Args:
        X: shape=(4, 18, 25) the current anchor type for all points in the feature map
        T: regression layer shape=(4, 18, 25)

    Returns:
        X: regressed position and size for current anchor
    """
    try:
        x = X[0, :, :]
        y = X[1, :, :]
        w = X[2, :, :]
        h = X[3, :, :]

        tx = T[0, :, :]
        ty = T[1, :, :]
        tw = T[2, :, :]
        th = T[3, :, :]

        cx = x + w/2.
        cy = y + h/2.
        cx1 = tx * w + cx
        cy1 = ty * h + cy

        w1 = np.exp(tw.astype(np.float64)) * w
        h1 = np.exp(th.astype(np.float64)) * h
        x1 = cx1 - w1/2.
        y1 = cy1 - h1/2.

        x1 = np.round(x1)
        y1 = np.round(y1)
        w1 = np.round(w1)
        h1 = np.round(h1)
        return np.stack([x1, y1, w1, h1])
    except Exception as e:
        print(e)
        return X
    
def apply_regr(x, y, w, h, tx, ty, tw, th):
    # Apply regression to x, y, w and h
    try:
        cx = x + w/2.
        cy = y + h/2.
        cx1 = tx * w + cx
        cy1 = ty * h + cy
        w1 = math.exp(tw) * w
        h1 = math.exp(th) * h
        x1 = cx1 - w1/2.
        y1 = cy1 - h1/2.
        x1 = int(round(x1))
        y1 = int(round(y1))
        w1 = int(round(w1))
        h1 = int(round(h1))

        return x1, y1, w1, h1

    except ValueError:
        return x, y, w, h
    except OverflowError:
        return x, y, w, h
    except Exception as e:
        print(e)
        return x, y, w, h

def calc_iou(R, img_data, C, class_mapping):
    """Converts from (x1,y1,x2,y2) to (x,y,w,h) format

    Args:
        R: bboxes, probs
    """
    bboxes = img_data['bboxes']
    (width, height) = (img_data['width'], img_data['height'])
    # get image dimensions for resizing
    (resized_width, resized_height) = get_new_img_size(width, height, C.im_size)

    gta = np.zeros((len(bboxes), 4))

    for bbox_num, bbox in enumerate(bboxes):
        # get the GT box coordinates, and resize to account for image resizing
        # gta[bbox_num, 0] = (40 * (600 / 800)) / 16 = int(round(1.875)) = 2 (x in feature map)
        gta[bbox_num, 0] = int(round(bbox['x1'] * (resized_width / float(width))/C.rpn_stride))
        gta[bbox_num, 1] = int(round(bbox['x2'] * (resized_width / float(width))/C.rpn_stride))
        gta[bbox_num, 2] = int(round(bbox['y1'] * (resized_height / float(height))/C.rpn_stride))
        gta[bbox_num, 3] = int(round(bbox['y2'] * (resized_height / float(height))/C.rpn_stride))

    x_roi = []
    y_class_num = []
    y_class_regr_coords = []
    y_class_regr_label = []
    IoUs = [] # for debugging only

    # R.shape[0]: number of bboxes (=300 from non_max_suppression)
    for ix in range(R.shape[0]):
        (x1, y1, x2, y2) = R[ix, :]
        x1 = int(round(x1))
        y1 = int(round(y1))
        x2 = int(round(x2))
        y2 = int(round(y2))

        best_iou = 0.0
        best_bbox = -1
        # Iterate through all the ground-truth bboxes to calculate the iou
        for bbox_num in range(len(bboxes)):
            curr_iou = iou([gta[bbox_num, 0], gta[bbox_num, 2], gta[bbox_num, 1], gta[bbox_num, 3]], [x1, y1, x2, y2])

            # Find out the corresponding ground-truth bbox_num with larget iou
            if curr_iou > best_iou:
                best_iou = curr_iou
                best_bbox = bbox_num

        if best_iou < C.classifier_min_overlap:
                continue
        else:
            w = x2 - x1
            h = y2 - y1
            x_roi.append([x1, y1, w, h])
            IoUs.append(best_iou)

            if C.classifier_min_overlap <= best_iou < C.classifier_max_overlap:
                # hard negative example
                cls_name = 'bg'
            elif C.classifier_max_overlap <= best_iou:
                cls_name = bboxes[best_bbox]['class']
                cxg = (gta[best_bbox, 0] + gta[best_bbox, 1]) / 2.0
                cyg = (gta[best_bbox, 2] + gta[best_bbox, 3]) / 2.0

                cx = x1 + w / 2.0
                cy = y1 + h / 2.0

                tx = (cxg - cx) / float(w)
                ty = (cyg - cy) / float(h)
                tw = np.log((gta[best_bbox, 1] - gta[best_bbox, 0]) / float(w))
                th = np.log((gta[best_bbox, 3] - gta[best_bbox, 2]) / float(h))
            else:
                print('roi = {}'.format(best_iou))
                raise RuntimeError

        class_num = class_mapping[cls_name]
        class_label = len(class_mapping) * [0]
        class_label[class_num] = 1
        y_class_num.append(copy.deepcopy(class_label))
        coords = [0] * 4 * (len(class_mapping) - 1)
        labels = [0] * 4 * (len(class_mapping) - 1)
        if cls_name != 'bg':
            label_pos = 4 * class_num
            sx, sy, sw, sh = C.classifier_regr_std
            coords[label_pos:4+label_pos] = [sx*tx, sy*ty, sw*tw, sh*th]
            labels[label_pos:4+label_pos] = [1, 1, 1, 1]
            y_class_regr_coords.append(copy.deepcopy(coords))
            y_class_regr_label.append(copy.deepcopy(labels))
        else:
            y_class_regr_coords.append(copy.deepcopy(coords))
            y_class_regr_label.append(copy.deepcopy(labels))

    if len(x_roi) == 0:
        return None, None, None, None

    # bboxes that iou > C.classifier_min_overlap for all gt bboxes in 300 non_max_suppression bboxes
    X = np.array(x_roi)
    # one hot code for bboxes from above => x_roi (X)
    Y1 = np.array(y_class_num)
    # corresponding labels and corresponding gt bboxes
    Y2 = np.concatenate([np.array(y_class_regr_label),np.array(y_class_regr_coords)],axis=1)

    return np.expand_dims(X, axis=0), np.expand_dims(Y1, axis=0), np.expand_dims(Y2, axis=0), IoUs
In [ ]:
def rpn_to_roi(rpn_layer, regr_layer, C, dim_ordering, use_regr=True, max_boxes=300,overlap_thresh=0.9):
	"""Convert rpn layer to roi bboxes

	Args: (num_anchors = 9)
		rpn_layer: output layer for rpn classification 
			shape (1, feature_map.height, feature_map.width, num_anchors)
			Might be (1, 18, 25, 18) if resized image is 400 width and 300
		regr_layer: output layer for rpn regression
			shape (1, feature_map.height, feature_map.width, num_anchors)
			Might be (1, 18, 25, 72) if resized image is 400 width and 300
		C: config
		use_regr: Wether to use bboxes regression in rpn
		max_boxes: max bboxes number for non-max-suppression (NMS)
		overlap_thresh: If iou in NMS is larger than this threshold, drop the box

	Returns:
		result: boxes from non-max-suppression (shape=(300, 4))
			boxes: coordinates for bboxes (on the feature map)
	"""
	regr_layer = regr_layer / C.std_scaling

	anchor_sizes = C.anchor_box_scales   # (3 in here)
	anchor_ratios = C.anchor_box_ratios  # (3 in here)

	assert rpn_layer.shape[0] == 1

	(rows, cols) = rpn_layer.shape[1:3]

	curr_layer = 0

	# A.shape = (4, feature_map.height, feature_map.width, num_anchors) 
	# Might be (4, 18, 25, 18) if resized image is 400 width and 300
	# A is the coordinates for 9 anchors for every point in the feature map 
	# => all 18x25x9=4050 anchors cooridnates
	A = np.zeros((4, rpn_layer.shape[1], rpn_layer.shape[2], rpn_layer.shape[3]))

	for anchor_size in anchor_sizes:
		for anchor_ratio in anchor_ratios:
			# anchor_x = (128 * 1) / 16 = 8  => width of current anchor
			# anchor_y = (128 * 2) / 16 = 16 => height of current anchor
			anchor_x = (anchor_size * anchor_ratio[0])/C.rpn_stride
			anchor_y = (anchor_size * anchor_ratio[1])/C.rpn_stride
			
			# curr_layer: 0~8 (9 anchors)
			# the Kth anchor of all position in the feature map (9th in total)
			regr = regr_layer[0, :, :, 4 * curr_layer:4 * curr_layer + 4] # shape => (18, 25, 4)
			regr = np.transpose(regr, (2, 0, 1)) # shape => (4, 18, 25)

			# Create 18x25 mesh grid
			# For every point in x, there are all the y points and vice versa
			# X.shape = (18, 25)
			# Y.shape = (18, 25)
			X, Y = np.meshgrid(np.arange(cols),np. arange(rows))

			# Calculate anchor position and size for each feature map point
			A[0, :, :, curr_layer] = X - anchor_x/2 # Top left x coordinate
			A[1, :, :, curr_layer] = Y - anchor_y/2 # Top left y coordinate
			A[2, :, :, curr_layer] = anchor_x       # width of current anchor
			A[3, :, :, curr_layer] = anchor_y       # height of current anchor

			# Apply regression to x, y, w and h if there is rpn regression layer
			if use_regr:
				A[:, :, :, curr_layer] = apply_regr_np(A[:, :, :, curr_layer], regr)

			# Avoid width and height exceeding 1
			A[2, :, :, curr_layer] = np.maximum(1, A[2, :, :, curr_layer])
			A[3, :, :, curr_layer] = np.maximum(1, A[3, :, :, curr_layer])

			# Convert (x, y , w, h) to (x1, y1, x2, y2)
			# x1, y1 is top left coordinate
			# x2, y2 is bottom right coordinate
			A[2, :, :, curr_layer] += A[0, :, :, curr_layer]
			A[3, :, :, curr_layer] += A[1, :, :, curr_layer]

			# Avoid bboxes drawn outside the feature map
			A[0, :, :, curr_layer] = np.maximum(0, A[0, :, :, curr_layer])
			A[1, :, :, curr_layer] = np.maximum(0, A[1, :, :, curr_layer])
			A[2, :, :, curr_layer] = np.minimum(cols-1, A[2, :, :, curr_layer])
			A[3, :, :, curr_layer] = np.minimum(rows-1, A[3, :, :, curr_layer])

			curr_layer += 1

	all_boxes = np.reshape(A.transpose((0, 3, 1, 2)), (4, -1)).transpose((1, 0))  # shape=(4050, 4)
	all_probs = rpn_layer.transpose((0, 3, 1, 2)).reshape((-1))                   # shape=(4050,)

	x1 = all_boxes[:, 0]
	y1 = all_boxes[:, 1]
	x2 = all_boxes[:, 2]
	y2 = all_boxes[:, 3]

	# Find out the bboxes which is illegal and delete them from bboxes list
	idxs = np.where((x1 - x2 >= 0) | (y1 - y2 >= 0))

	all_boxes = np.delete(all_boxes, idxs, 0)
	all_probs = np.delete(all_probs, idxs, 0)

	# Apply non_max_suppression
	# Only extract the bboxes. Don't need rpn probs in the later process
	result = non_max_suppression_fast(all_boxes, all_probs, overlap_thresh=overlap_thresh, max_boxes=max_boxes)[0]

	return result

In [ ]:
cwd = os.getcwd()
test_path = os.path.join(cwd, 'dataset', 'test')
test_output_path = os.path.join(cwd, 'test_output')

num_rois = 4

horizontal_flips = False
vertical_flips = False
rot_90 = False

C = Config()

if os.path.isfile(C.config_path):
	C = pickle.load(open(C.config_path, 'rb'))
else:
	pickle.dump(C, open(C.config_path, 'wb'))
In [ ]:
# Plot training progress

record_df = pd.read_csv(C.record_path)

r_epochs = len(record_df)

plt.figure(figsize=(15,5))
plt.subplot(1,2,1)
plt.plot(np.arange(0, r_epochs), record_df['mean_overlapping_bboxes'], 'r')
plt.title('mean_overlapping_bboxes')

plt.subplot(1,2,2)
plt.plot(np.arange(0, r_epochs), record_df['class_acc'], 'r')
plt.title('class_acc')

plt.show()

plt.figure(figsize=(15,5))

plt.subplot(1,2,1)
plt.plot(np.arange(0, r_epochs), record_df['loss_rpn_cls'], 'r')
plt.title('loss_rpn_cls')

plt.subplot(1,2,2)
plt.plot(np.arange(0, r_epochs), record_df['loss_rpn_regr'], 'r')
plt.title('loss_rpn_regr')
plt.show()
plt.figure(figsize=(15,5))
plt.subplot(1,2,1)
plt.plot(np.arange(0, r_epochs), record_df['loss_class_cls'], 'r')
plt.title('loss_class_cls')

plt.subplot(1,2,2)
plt.plot(np.arange(0, r_epochs), record_df['loss_class_regr'], 'r')
plt.title('loss_class_regr')
plt.show()
plt.figure(figsize=(15,5))
plt.subplot(1,2,1)
plt.plot(np.arange(0, r_epochs), record_df['curr_loss'], 'r')
plt.title('total_loss')

plt.subplot(1,2,2)
plt.plot(np.arange(0, r_epochs), record_df['elapsed_time'], 'r')
plt.title('elapsed_time')

plt.show()

Test¶

In [ ]:
all_data, classes_count, class_mapping = get_data(test_path)

if 'bg' not in classes_count:
	classes_count['bg'] = 0
	class_mapping['bg'] = len(class_mapping)
	
print(len(all_data))
print(classes_count)
print(class_mapping)
Parsing annotation files
110
{'unpolished': 26, 'crack': 41, 'pit': 28, 'burr': 9, 'no_defect': 45, 'bg': 0}
{'burr': 0, 'crack': 1, 'pit': 2, 'unpolished': 3, 'no_defect': 4, 'bg': 5}
In [ ]:
def format_img_size(img, C):
	""" formats the image size based on config """
	img_min_side = float(C.im_size)
	(height,width,_) = img.shape
		
	if width <= height:
		ratio = img_min_side/width
		new_height = int(ratio * height)
		new_width = int(img_min_side)
	else:
		ratio = img_min_side/height
		new_width = int(ratio * width)
		new_height = int(img_min_side)
	img = cv2.resize(img, (new_width, new_height), interpolation=cv2.INTER_CUBIC)
	return img, ratio	

def format_img_channels(img, C):
	""" formats the image channels based on config """
	img = img[:, :, (2, 1, 0)]
	img = img.astype(np.float32)
	img[:, :, 0] -= C.img_channel_mean[0]
	img[:, :, 1] -= C.img_channel_mean[1]
	img[:, :, 2] -= C.img_channel_mean[2]
	img /= C.img_scaling_factor
	img = np.transpose(img, (2, 0, 1))
	img = np.expand_dims(img, axis=0)
	return img

def format_img(img, C):
	""" formats an image for model prediction based on config """
	img, ratio = format_img_size(img, C)
	img = format_img_channels(img, C)
	return img, ratio

# Method to transform the coordinates of the bounding box to its original size
def get_real_coordinates(ratio, x1, y1, x2, y2):

	real_x1 = int(round(x1 // ratio))
	real_y1 = int(round(y1 // ratio))
	real_x2 = int(round(x2 // ratio))
	real_y2 = int(round(y2 // ratio))

	return (real_x1, real_y1, real_x2 ,real_y2)
In [ ]:
if C.network == 'vgg':
	num_features = 512
else:
	num_features = 1024

input_shape_img = (None, None, 3)
input_shape_features = (None, None, num_features)

img_input = Input(shape=input_shape_img)
roi_input = Input(shape=(C.num_rois, 4))
feature_map_input = Input(shape=input_shape_features)

# define the base network (VGG here, can be Resnet50, Inception, etc)
if C.network == 'vgg':
	shared_layers = nn_base(img_input, trainable=True)
else:
	shared_layers = nn_base_resnet(img_input, trainable=True)

# define the RPN, built on the base layers
num_anchors = len(C.anchor_box_scales) * len(C.anchor_box_ratios) # 9	

if C.network == 'vgg':
	rpn_layers = rpn_layer(shared_layers, num_anchors)
	classifier = classifier_layer(feature_map_input, roi_input, C.num_rois, nb_classes=len(class_mapping))
else:
	rpn_layers = rpn_resnet(shared_layers, num_anchors)
	classifier = classifier_resnet(feature_map_input, roi_input, C.num_rois, nb_classes=len(class_mapping))

model_rpn = Model(img_input, rpn_layers)
model_classifier_only = Model([feature_map_input, roi_input], classifier)

model_classifier = Model([feature_map_input, roi_input], classifier)

print('Loading weights from {}'.format(C.model_path))
model_rpn.load_weights(C.model_path, by_name=True)
model_classifier.load_weights(C.model_path, by_name=True)

model_rpn.compile(optimizer='sgd', loss='mse')
model_classifier.compile(optimizer='sgd', loss='mse')
WARNING:tensorflow:From c:\Users\luizh\anaconda3\Lib\site-packages\keras\src\backend.py:1398: The name tf.executing_eagerly_outside_functions is deprecated. Please use tf.compat.v1.executing_eagerly_outside_functions instead.

WARNING:tensorflow:From c:\Users\luizh\anaconda3\Lib\site-packages\keras\src\backend.py:3527: The name tf.nn.fused_batch_norm is deprecated. Please use tf.compat.v1.nn.fused_batch_norm instead.

Roi pool shape:  (1, 4, 14, 14, 1024)
Loading weights from model/model_frcnn_resnet_640_big_anchor.h5
WARNING:tensorflow:From c:\Users\luizh\anaconda3\Lib\site-packages\keras\src\optimizers\__init__.py:309: The name tf.train.Optimizer is deprecated. Please use tf.compat.v1.train.Optimizer instead.

In [ ]:
inv_mapping = {v: k for k, v in class_mapping.items()}
class_to_color = {inv_mapping[v]: np.random.randint(0, 255, 3) for v in inv_mapping}
In [ ]:
# if the box classification value is less than this, we ignore this box
bbox_threshold = 0.7

# Test 5 images
#all_data = all_data[:5]

# init confusion matrix
conf_mat = np.zeros((len(classes_count), len(classes_count)))



for idx, img_data in enumerate(all_data):
	if not img_data['img_path'].endswith(('.jpeg', '.png', '.jpg')):
		continue

	print(img_data['img_path'])
	start_time = time.time()

	img = cv2.imread(img_data['img_path'])

	X, ratio = format_img(img, C)

	X = np.transpose(X, (0, 2, 3, 1))

	# get output layer Y1, Y2 from the RPN and the feature maps F
	# Y1: y_rpn_cls
	# Y2: y_rpn_regr
	[Y1, Y2, F] = model_rpn.predict(X, verbose=0)

	# Get bboxes by applying Non-max Suppression
	# R.shape = (300, 4)
	R = rpn_to_roi(Y1, Y2, C, K.image_data_format(), overlap_thresh=0.7)

	# convert from (x1, y1, x2, y2) to (x, y, w, h)
	R[:, 2] -= R[:, 0]
	R[:, 3] -= R[:, 1]

	# apply the spatial pyramid pooling to the proposed regions
	bboxes = {}
	probs = {}

	# ground truth bboxes for current image
	ground_truth = []

	# IoUs for current image
	all_ious = []

	for jk in range(R.shape[0]//C.num_rois + 1):
		ROIs = np.expand_dims(R[C.num_rois*jk:C.num_rois*(jk+1), :], axis=0)
		if ROIs.shape[1] == 0:
			break
        
		if jk == R.shape[0]//C.num_rois:
			#pad R
			curr_shape = ROIs.shape
			target_shape = (curr_shape[0],C.num_rois,curr_shape[2])
			ROIs_padded = np.zeros(target_shape).astype(ROIs.dtype)
			ROIs_padded[:, :curr_shape[1], :] = ROIs
			ROIs_padded[0, curr_shape[1]:, :] = ROIs[0, 0, :]
			ROIs = ROIs_padded

		[P_cls, P_regr] = model_classifier_only.predict([F, ROIs], verbose=0)

        # Calculate bboxes coordinates on resized image
		for ii in range(P_cls.shape[1]):
			# Ignore 'bg' class
			if np.max(P_cls[0, ii, :]) < bbox_threshold or np.argmax(P_cls[0, ii, :]) == (P_cls.shape[2] - 1):
				continue

			cls_name = inv_mapping[np.argmax(P_cls[0, ii, :])]

			if cls_name not in bboxes:
				bboxes[cls_name] = []
				probs[cls_name] = []

			(x, y, w, h) = ROIs[0, ii, :]

			cls_num = np.argmax(P_cls[0, ii, :])
			try:
				(tx, ty, tw, th) = P_regr[0, ii, 4*cls_num:4*(cls_num+1)]
				tx /= C.classifier_regr_std[0]
				ty /= C.classifier_regr_std[1]
				tw /= C.classifier_regr_std[2]
				th /= C.classifier_regr_std[3]
				x, y, w, h = apply_regr(x, y, w, h, tx, ty, tw, th)
			except:
				pass
			bboxes[cls_name].append([C.rpn_stride*x, C.rpn_stride*y, C.rpn_stride*(x+w), C.rpn_stride*(y+h)])
			probs[cls_name].append(np.max(P_cls[0, ii, :]))

	all_dets = []

	for key in bboxes:
		bbox = np.array(bboxes[key])

		new_boxes, new_probs = non_max_suppression_fast(bbox, np.array(probs[key]), overlap_thresh=0.2)

		for jk in range(new_boxes.shape[0]):
			(x1, y1, x2, y2) = new_boxes[jk,:]

			# Calculate real coordinates on original image
			(real_x1, real_y1, real_x2, real_y2) = get_real_coordinates(ratio, x1, y1, x2, y2)

			cv2.rectangle(img, (real_x1, real_y1), (real_x2, real_y2), (int(class_to_color[key][0]), int(class_to_color[key][1]), int(class_to_color[key][2])),2)

			textLabel = '{}: {}'.format(key,int(100*new_probs[jk]))
			all_dets.append((key,100*new_probs[jk]))

			(retval,baseLine) = cv2.getTextSize(textLabel,cv2.FONT_HERSHEY_COMPLEX,1,1)
			textOrg = (real_x1, real_y1-0)

			cv2.rectangle(img, (textOrg[0] - 5, textOrg[1]+baseLine - 5), (textOrg[0]+retval[0] + 5, textOrg[1]-retval[1] - 5), (0, 0, 0), 2)
			cv2.rectangle(img, (textOrg[0] - 5,textOrg[1]+baseLine - 5), (textOrg[0]+retval[0] + 5, textOrg[1]-retval[1] - 5), (255, 255, 255), -1)
			cv2.putText(img, textLabel, textOrg, cv2.FONT_HERSHEY_DUPLEX, 1, (0, 0, 0), 1)

	

	# Include ground-truth bboxes in the image
	for gtbbox in img_data['bboxes']:
		ground_truth.append(gtbbox)
		x1, y1, x2, y2 = gtbbox['x1'], gtbbox['y1'], gtbbox['x2'], gtbbox['y2']
		cv2.rectangle(img, (x1, y1), (x2, y2), (0, 255, 0), 2)

	# create a list of all predicted bboxes
	bboxes_list = []
	for key in bboxes:
		for bbox in bboxes[key]:
			bboxes_list.append([key,bbox])

	# for each ground truth bbox, find the predicted bbox with the highest IoU
	for gts in ground_truth:
		best_iou = 0
		best_pred_idx = -1

		for pred_idx, pred in enumerate(bboxes_list):
			pred_cls, pred_bbox = pred
			real_x1, real_y1, real_x2, real_y2 = get_real_coordinates(ratio, pred_bbox[0], pred_bbox[1], pred_bbox[2], pred_bbox[3])
			iou_val = iou((gts['x1'], gts['y1'], gts['x2'], gts['y2']), (real_x1, real_y1, real_x2, real_y2))
			if iou_val > best_iou:
				best_iou = iou_val
				best_pred_idx = pred_idx

		# use the best predicted bbox to update the confusion matrix
		if best_pred_idx >= 0:
			conf_mat[class_mapping[bboxes_list[best_pred_idx][0]], class_mapping[gts['class']]] += 1
			all_ious.append(best_iou)
		else:
			all_ious.append(0)
		

	print('Elapsed time = {}'.format(time.time() - start_time))
	print(all_dets)
	print(ground_truth)
	print(all_ious)
	for i in range(conf_mat.shape[0]):
		for j in range(conf_mat.shape[1]):
			print(conf_mat[i][j]," ", end="")
		print()
	plt.figure(figsize=(10, 10))
	plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
	plt.show()


# Compute Confusion Matrix
tp = np.diag(conf_mat)
fp = np.sum(conf_mat, axis=0) - tp
fn = np.sum(conf_mat, axis=1) - tp
tn = np.sum(conf_mat) - (fp + fn + tp)

print("True Positives: ", tp)
print("False Positives: ", fp)
print("False Negatives: ", fn)
print("True Negatives: ", tn)

precision = tp / (tp + fp)
recall = tp / (tp + fn)

print("Precision: ", precision)
print("Recall: ", recall)

plt.figure(figsize=(10, 10))
plt.imshow(conf_mat, interpolation='nearest', cmap=plt.cm.Blues)
plt.title('Confusion Matrix')
plt.colorbar()
tick_marks = np.arange(len(classes_count))
plt.xticks(tick_marks, ["burr","crack","pit","unpolished","no_defect", "bg"], rotation=45)
plt.yticks(tick_marks, ["burr","crack","pit","unpolished","no_defect", "bg"])
plt.ylabel('Predicted label')
plt.xlabel('True label')

# Add the values in each cell
for i in range(conf_mat.shape[0]):
	for j in range(conf_mat.shape[1]):
		plt.text(j, i, format(conf_mat[i, j]),
			horizontalalignment="center",
			color="white" if conf_mat[i, j] > conf_mat.max() / 2. else "black")
		
plt.show()
	

	
c:\Users\luizh\Desktop\estagio\notebooks\casting\dataset\test\images\cast_def_0_1019_jpeg.rf.c96a3513d835c3d9bedd9c2dbd697f61.jpg
Elapsed time = 10.910101652145386
[('unpolished', 99.9826729297638), ('crack', 96.15378379821777)]
[{'class': 'unpolished', 'x1': 53, 'x2': 569, 'y1': 59, 'y2': 590}, {'class': 'crack', 'x1': 148, 'x2': 213, 'y1': 406, 'y2': 464}]
[0.9487541274493841, 0.4372929483110996]
0.0  0.0  0.0  0.0  0.0  0.0  
0.0  1.0  0.0  0.0  0.0  0.0  
0.0  0.0  0.0  0.0  0.0  0.0  
0.0  0.0  0.0  1.0  0.0  0.0  
0.0  0.0  0.0  0.0  0.0  0.0  
0.0  0.0  0.0  0.0  0.0  0.0  
c:\Users\luizh\Desktop\estagio\notebooks\casting\dataset\test\images\cast_def_0_1139_jpeg.rf.5ac61906a0502e1fd2ee6b486e6e2b24.jpg
Elapsed time = 8.547050476074219
[('no_defect', 99.97889399528503)]
[{'class': 'pit', 'x1': 225, 'x2': 252, 'y1': 76, 'y2': 96}]
[0.0019441244239561343]
0.0  0.0  0.0  0.0  0.0  0.0  
0.0  1.0  0.0  0.0  0.0  0.0  
0.0  0.0  0.0  0.0  0.0  0.0  
0.0  0.0  0.0  1.0  0.0  0.0  
0.0  0.0  1.0  0.0  0.0  0.0  
0.0  0.0  0.0  0.0  0.0  0.0  
c:\Users\luizh\Desktop\estagio\notebooks\casting\dataset\test\images\cast_def_0_1225_jpeg.rf.f4f5e755ddf8942877eab865162c07c5.jpg
Elapsed time = 8.213411092758179
[('unpolished', 99.99843835830688), ('crack', 82.64904618263245)]
[{'class': 'crack', 'x1': 405, 'x2': 450, 'y1': 163, 'y2': 201}, {'class': 'unpolished', 'x1': 57, 'x2': 593, 'y1': 53, 'y2': 595}]
[0.6865546215602712, 0.9462824865475685]
0.0  0.0  0.0  0.0  0.0  0.0  
0.0  2.0  0.0  0.0  0.0  0.0  
0.0  0.0  0.0  0.0  0.0  0.0  
0.0  0.0  0.0  2.0  0.0  0.0  
0.0  0.0  1.0  0.0  0.0  0.0  
0.0  0.0  0.0  0.0  0.0  0.0  
c:\Users\luizh\Desktop\estagio\notebooks\casting\dataset\test\images\cast_def_0_1313_jpeg.rf.c368f21a9af4e929774b74d999889af8.jpg
Elapsed time = 8.24054479598999
[('unpolished', 99.98692274093628), ('no_defect', 79.81277108192444), ('pit', 92.93450713157654)]
[{'class': 'unpolished', 'x1': 32, 'x2': 603, 'y1': 29, 'y2': 602}, {'class': 'crack', 'x1': 261, 'x2': 312, 'y1': 111, 'y2': 149}, {'class': 'crack', 'x1': 425, 'x2': 480, 'y1': 169, 'y2': 212}]
[0.965683738572695, 0.6558627260934877, 0.007998511904734853]
0.0  0.0  0.0  0.0  0.0  0.0  
0.0  2.0  0.0  0.0  0.0  0.0  
0.0  1.0  0.0  0.0  0.0  0.0  
0.0  1.0  0.0  3.0  0.0  0.0  
0.0  0.0  1.0  0.0  0.0  0.0  
0.0  0.0  0.0  0.0  0.0  0.0  
c:\Users\luizh\Desktop\estagio\notebooks\casting\dataset\test\images\cast_def_0_138_jpeg.rf.611379c4d69f5f37706b0d18ba61aebc.jpg
Elapsed time = 8.33954644203186
[('no_defect', 99.99514818191528), ('pit', 95.65379023551941)]
[{'class': 'pit', 'x1': 73, 'x2': 105, 'y1': 498, 'y2': 535}]
[0.5454545451446281]
0.0  0.0  0.0  0.0  0.0  0.0  
0.0  2.0  0.0  0.0  0.0  0.0  
0.0  1.0  1.0  0.0  0.0  0.0  
0.0  1.0  0.0  3.0  0.0  0.0  
0.0  0.0  1.0  0.0  0.0  0.0  
0.0  0.0  0.0  0.0  0.0  0.0  
c:\Users\luizh\Desktop\estagio\notebooks\casting\dataset\test\images\cast_def_0_1728_jpeg.rf.c4f8eba1b4fede32163ba146a851427b.jpg
Elapsed time = 8.764941453933716
[('burr', 99.99566078186035), ('crack', 96.39909863471985)]
[{'class': 'burr', 'x1': 38, 'x2': 599, 'y1': 39, 'y2': 605}]
[0.9370497964268127]
1.0  0.0  0.0  0.0  0.0  0.0  
0.0  2.0  0.0  0.0  0.0  0.0  
0.0  1.0  1.0  0.0  0.0  0.0  
0.0  1.0  0.0  3.0  0.0  0.0  
0.0  0.0  1.0  0.0  0.0  0.0  
0.0  0.0  0.0  0.0  0.0  0.0  
c:\Users\luizh\Desktop\estagio\notebooks\casting\dataset\test\images\cast_def_0_1778_jpeg.rf.84fce609adc9552561b3d4de82db20f4.jpg
Elapsed time = 8.100405216217041
[('unpolished', 99.98433589935303), ('pit', 95.23783922195435)]
[{'class': 'unpolished', 'x1': 41, 'x2': 584, 'y1': 51, 'y2': 589}, {'class': 'pit', 'x1': 142, 'x2': 206, 'y1': 506, 'y2': 553}]
[0.9619440437214718, 0.7184850195821127]
1.0  0.0  0.0  0.0  0.0  0.0  
0.0  2.0  0.0  0.0  0.0  0.0  
0.0  1.0  2.0  0.0  0.0  0.0  
0.0  1.0  0.0  4.0  0.0  0.0  
0.0  0.0  1.0  0.0  0.0  0.0  
0.0  0.0  0.0  0.0  0.0  0.0  
c:\Users\luizh\Desktop\estagio\notebooks\casting\dataset\test\images\cast_def_0_1784_jpeg.rf.1f358ab882e4fdb193240413c1a4f082.jpg
Elapsed time = 8.079025745391846
[('unpolished', 99.98325109481812), ('crack', 98.73186945915222)]
[{'class': 'crack', 'x1': 471, 'x2': 500, 'y1': 224, 'y2': 258}, {'class': 'unpolished', 'x1': 70, 'x2': 600, 'y1': 36, 'y2': 606}]
[0.6611570242469776, 0.963885865336638]
1.0  0.0  0.0  0.0  0.0  0.0  
0.0  3.0  0.0  0.0  0.0  0.0  
0.0  1.0  2.0  0.0  0.0  0.0  
0.0  1.0  0.0  5.0  0.0  0.0  
0.0  0.0  1.0  0.0  0.0  0.0  
0.0  0.0  0.0  0.0  0.0  0.0  
c:\Users\luizh\Desktop\estagio\notebooks\casting\dataset\test\images\cast_def_0_1849_jpeg.rf.06d1217ac7fd2307c75b265f94ff2e48.jpg
Elapsed time = 8.08500361442566
[('no_defect', 99.99772310256958)]
[{'class': 'pit', 'x1': 525, 'x2': 549, 'y1': 108, 'y2': 145}]
[0.003000648788917196]
1.0  0.0  0.0  0.0  0.0  0.0  
0.0  3.0  0.0  0.0  0.0  0.0  
0.0  1.0  2.0  0.0  0.0  0.0  
0.0  1.0  0.0  5.0  0.0  0.0  
0.0  0.0  2.0  0.0  0.0  0.0  
0.0  0.0  0.0  0.0  0.0  0.0  
c:\Users\luizh\Desktop\estagio\notebooks\casting\dataset\test\images\cast_def_0_2010_jpeg.rf.be75792dfa1625cb574b9fc9d44b5ba0.jpg
Elapsed time = 9.22516679763794
[('unpolished', 99.98959302902222), ('crack', 82.37239122390747)]
[{'class': 'pit', 'x1': 144, 'x2': 188, 'y1': 367, 'y2': 413}, {'class': 'crack', 'x1': 139, 'x2': 233, 'y1': 492, 'y2': 570}]
[0.5059288535049759, 0.02892992424231009]
1.0  0.0  0.0  0.0  0.0  0.0  
0.0  3.0  1.0  0.0  0.0  0.0  
0.0  1.0  2.0  0.0  0.0  0.0  
0.0  2.0  0.0  5.0  0.0  0.0  
0.0  0.0  2.0  0.0  0.0  0.0  
0.0  0.0  0.0  0.0  0.0  0.0  
c:\Users\luizh\Desktop\estagio\notebooks\casting\dataset\test\images\cast_def_0_2057_jpeg.rf.d868a313022dfcfbb26b8b2e6d0f5dbb.jpg
Elapsed time = 8.300770998001099
[('no_defect', 99.91551637649536), ('pit', 99.89144802093506)]
[{'class': 'pit', 'x1': 316, 'x2': 355, 'y1': 2, 'y2': 40}]
[0.6209573087833393]
1.0  0.0  0.0  0.0  0.0  0.0  
0.0  3.0  1.0  0.0  0.0  0.0  
0.0  1.0  3.0  0.0  0.0  0.0  
0.0  2.0  0.0  5.0  0.0  0.0  
0.0  0.0  2.0  0.0  0.0  0.0  
0.0  0.0  0.0  0.0  0.0  0.0  
c:\Users\luizh\Desktop\estagio\notebooks\casting\dataset\test\images\cast_def_0_2437_jpeg.rf.a966c95fb50ddbd585a86a533918f199.jpg
Elapsed time = 8.222599983215332
[('unpolished', 99.93728995323181), ('pit', 99.630606174469)]
[{'class': 'pit', 'x1': 65, 'x2': 132, 'y1': 422, 'y2': 496}]
[0.8028673833526747]
1.0  0.0  0.0  0.0  0.0  0.0  
0.0  3.0  1.0  0.0  0.0  0.0  
0.0  1.0  4.0  0.0  0.0  0.0  
0.0  2.0  0.0  5.0  0.0  0.0  
0.0  0.0  2.0  0.0  0.0  0.0  
0.0  0.0  0.0  0.0  0.0  0.0  
c:\Users\luizh\Desktop\estagio\notebooks\casting\dataset\test\images\cast_def_0_2641_jpeg.rf.c3c9283e26c7cdcfeb16877d5c280341.jpg
Elapsed time = 8.303519248962402
[('unpolished', 99.96590614318848), ('no_defect', 80.454021692276)]
[{'class': 'unpolished', 'x1': 10, 'x2': 578, 'y1': 38, 'y2': 587}, {'class': 'crack', 'x1': 326, 'x2': 385, 'y1': 31, 'y2': 85}]
[0.9668167752617461, 0.010564367641309602]
1.0  0.0  0.0  0.0  0.0  0.0  
0.0  3.0  1.0  0.0  0.0  0.0  
0.0  1.0  4.0  0.0  0.0  0.0  
0.0  3.0  0.0  6.0  0.0  0.0  
0.0  0.0  2.0  0.0  0.0  0.0  
0.0  0.0  0.0  0.0  0.0  0.0  
c:\Users\luizh\Desktop\estagio\notebooks\casting\dataset\test\images\cast_def_0_2950_jpeg.rf.0ad9c4bff9dcb6431226be1351f7ed13.jpg
Elapsed time = 8.127502202987671
[('no_defect', 99.96843338012695), ('crack', 98.55595827102661)]
[{'class': 'crack', 'x1': 454, 'x2': 505, 'y1': 472, 'y2': 509}]
[0.5893060293555912]
1.0  0.0  0.0  0.0  0.0  0.0  
0.0  4.0  1.0  0.0  0.0  0.0  
0.0  1.0  4.0  0.0  0.0  0.0  
0.0  3.0  0.0  6.0  0.0  0.0  
0.0  0.0  2.0  0.0  0.0  0.0  
0.0  0.0  0.0  0.0  0.0  0.0  
c:\Users\luizh\Desktop\estagio\notebooks\casting\dataset\test\images\cast_def_0_2994_jpeg.rf.389183bc79926bc999f6f1d3441e9769.jpg
Elapsed time = 8.871199131011963
[('no_defect', 99.99449253082275), ('unpolished', 98.16113114356995), ('pit', 96.30794525146484)]
[{'class': 'pit', 'x1': 570, 'x2': 596, 'y1': 252, 'y2': 293}]
[0.5079365075700314]
1.0  0.0  0.0  0.0  0.0  0.0  
0.0  4.0  1.0  0.0  0.0  0.0  
0.0  1.0  5.0  0.0  0.0  0.0  
0.0  3.0  0.0  6.0  0.0  0.0  
0.0  0.0  2.0  0.0  0.0  0.0  
0.0  0.0  0.0  0.0  0.0  0.0  
c:\Users\luizh\Desktop\estagio\notebooks\casting\dataset\test\images\cast_def_0_2_jpeg.rf.e25025925940cb327c586f764881fcf0.jpg
Elapsed time = 8.112499713897705
[('no_defect', 99.94407296180725), ('unpolished', 92.45452284812927), ('pit', 99.56556558609009)]
[{'class': 'pit', 'x1': 169, 'x2': 194, 'y1': 137, 'y2': 161}]
[0.48310502238985836]
1.0  0.0  0.0  0.0  0.0  0.0  
0.0  4.0  1.0  0.0  0.0  0.0  
0.0  1.0  6.0  0.0  0.0  0.0  
0.0  3.0  0.0  6.0  0.0  0.0  
0.0  0.0  2.0  0.0  0.0  0.0  
0.0  0.0  0.0  0.0  0.0  0.0  
c:\Users\luizh\Desktop\estagio\notebooks\casting\dataset\test\images\cast_def_0_323_jpeg.rf.f35e3f940bd390bbb8aafcd45db75f7c.jpg
Elapsed time = 8.142350196838379
[('unpolished', 99.98997449874878), ('pit', 97.23237156867981)]
[{'class': 'unpolished', 'x1': 55, 'x2': 609, 'y1': 38, 'y2': 566}, {'class': 'pit', 'x1': 145, 'x2': 205, 'y1': 461, 'y2': 533}]
[0.9637427134840924, 0.6861313867048058]
1.0  0.0  0.0  0.0  0.0  0.0  
0.0  4.0  1.0  0.0  0.0  0.0  
0.0  1.0  7.0  0.0  0.0  0.0  
0.0  3.0  0.0  7.0  0.0  0.0  
0.0  0.0  2.0  0.0  0.0  0.0  
0.0  0.0  0.0  0.0  0.0  0.0  
c:\Users\luizh\Desktop\estagio\notebooks\casting\dataset\test\images\cast_def_0_3434_jpeg.rf.14f324bff1d94c7613aed2170268de36.jpg
Elapsed time = 8.225683212280273
[('unpolished', 99.854975938797), ('no_defect', 98.30596446990967), ('crack', 94.15826797485352)]
[{'class': 'pit', 'x1': 434, 'x2': 478, 'y1': 152, 'y2': 203}, {'class': 'crack', 'x1': 154, 'x2': 175, 'y1': 345, 'y2': 389}]
[0.7123493973221576, 0.0033266129032138297]
1.0  0.0  0.0  0.0  0.0  0.0  
0.0  4.0  2.0  0.0  0.0  0.0  
0.0  1.0  7.0  0.0  0.0  0.0  
0.0  4.0  0.0  7.0  0.0  0.0  
0.0  0.0  2.0  0.0  0.0  0.0  
0.0  0.0  0.0  0.0  0.0  0.0  
c:\Users\luizh\Desktop\estagio\notebooks\casting\dataset\test\images\cast_def_0_3544_jpeg.rf.7ff1ef44bacc888e7b2693884200123a.jpg
Elapsed time = 8.217574119567871
[('unpolished', 99.9576985836029), ('pit', 97.80615568161011)]
[{'class': 'pit', 'x1': 163, 'x2': 221, 'y1': 513, 'y2': 572}]
[0.8354492185460328]
1.0  0.0  0.0  0.0  0.0  0.0  
0.0  4.0  2.0  0.0  0.0  0.0  
0.0  1.0  8.0  0.0  0.0  0.0  
0.0  4.0  0.0  7.0  0.0  0.0  
0.0  0.0  2.0  0.0  0.0  0.0  
0.0  0.0  0.0  0.0  0.0  0.0  
c:\Users\luizh\Desktop\estagio\notebooks\casting\dataset\test\images\cast_def_0_356_jpeg.rf.88b9b5107e4284dce19873d41259659f.jpg
Elapsed time = 8.286465644836426
[('unpolished', 99.94237422943115), ('crack', 92.43990778923035)]
[{'class': 'crack', 'x1': 164, 'x2': 213, 'y1': 359, 'y2': 439}]
[0.6743295017542313]
1.0  0.0  0.0  0.0  0.0  0.0  
0.0  5.0  2.0  0.0  0.0  0.0  
0.0  1.0  8.0  0.0  0.0  0.0  
0.0  4.0  0.0  7.0  0.0  0.0  
0.0  0.0  2.0  0.0  0.0  0.0  
0.0  0.0  0.0  0.0  0.0  0.0  
c:\Users\luizh\Desktop\estagio\notebooks\casting\dataset\test\images\cast_def_0_3743_jpeg.rf.d38ffaf711864128544c007b4da95c43.jpg
Elapsed time = 8.279908418655396
[('unpolished', 99.99380111694336), ('crack', 87.98051476478577), ('crack', 82.68884420394897)]
[{'class': 'pit', 'x1': 162, 'x2': 195, 'y1': 236, 'y2': 270}, {'class': 'unpolished', 'x1': 50, 'x2': 613, 'y1': 72, 'y2': 600}, {'class': 'pit', 'x1': 151, 'x2': 190, 'y1': 385, 'y2': 430}]
[0.6227106223304575, 0.9583069118547931, 0.7617187496693929]
1.0  0.0  0.0  0.0  0.0  0.0  
0.0  5.0  4.0  0.0  0.0  0.0  
0.0  1.0  8.0  0.0  0.0  0.0  
0.0  4.0  0.0  8.0  0.0  0.0  
0.0  0.0  2.0  0.0  0.0  0.0  
0.0  0.0  0.0  0.0  0.0  0.0  
c:\Users\luizh\Desktop\estagio\notebooks\casting\dataset\test\images\cast_def_0_378_jpeg.rf.1a51446ea91952965c24cea952a1823d.jpg
Elapsed time = 8.768333435058594
[('unpolished', 99.99310970306396), ('crack', 97.62970805168152)]
[{'class': 'unpolished', 'x1': 47, 'x2': 562, 'y1': 32, 'y2': 606}, {'class': 'crack', 'x1': 150, 'x2': 190, 'y1': 178, 'y2': 222}]
[0.9907428008893426, 0.7638888885573399]
1.0  0.0  0.0  0.0  0.0  0.0  
0.0  6.0  4.0  0.0  0.0  0.0  
0.0  1.0  8.0  0.0  0.0  0.0  
0.0  4.0  0.0  9.0  0.0  0.0  
0.0  0.0  2.0  0.0  0.0  0.0  
0.0  0.0  0.0  0.0  0.0  0.0  
c:\Users\luizh\Desktop\estagio\notebooks\casting\dataset\test\images\cast_def_0_3866_jpeg.rf.895e73b595821ce55cbfaf6737ab692f.jpg
Elapsed time = 8.327004432678223
[('unpolished', 99.99417066574097), ('crack', 91.38643741607666)]
[{'class': 'pit', 'x1': 465, 'x2': 507, 'y1': 243, 'y2': 303}, {'class': 'unpolished', 'x1': 53, 'x2': 574, 'y1': 48, 'y2': 589}]
[0.49557522105620383, 0.9698782686912922]
1.0  0.0  0.0  0.0  0.0  0.0  
0.0  6.0  5.0  0.0  0.0  0.0  
0.0  1.0  8.0  0.0  0.0  0.0  
0.0  4.0  0.0  10.0  0.0  0.0  
0.0  0.0  2.0  0.0  0.0  0.0  
0.0  0.0  0.0  0.0  0.0  0.0  
c:\Users\luizh\Desktop\estagio\notebooks\casting\dataset\test\images\cast_def_0_4026_jpeg.rf.e8ad81f5f4015654a8f5aae5accf28d9.jpg
Elapsed time = 8.883452892303467
[('unpolished', 99.34883117675781), ('no_defect', 87.9649817943573), ('crack', 76.4386534690857)]
[{'class': 'pit', 'x1': 330, 'x2': 361, 'y1': 479, 'y2': 505}]
[0.4945756218924214]
1.0  0.0  0.0  0.0  0.0  0.0  
0.0  6.0  6.0  0.0  0.0  0.0  
0.0  1.0  8.0  0.0  0.0  0.0  
0.0  4.0  0.0  10.0  0.0  0.0  
0.0  0.0  2.0  0.0  0.0  0.0  
0.0  0.0  0.0  0.0  0.0  0.0  
c:\Users\luizh\Desktop\estagio\notebooks\casting\dataset\test\images\cast_def_0_4125_jpeg.rf.e0d3066233e99d1cb84d17226a7762e9.jpg
Elapsed time = 8.203611135482788
[('unpolished', 95.82507014274597), ('no_defect', 99.96979236602783), ('pit', 99.17795062065125)]
[{'class': 'pit', 'x1': 455, 'x2': 484, 'y1': 481, 'y2': 514}]
[0.6426202316396183]
1.0  0.0  0.0  0.0  0.0  0.0  
0.0  6.0  6.0  0.0  0.0  0.0  
0.0  1.0  9.0  0.0  0.0  0.0  
0.0  4.0  0.0  10.0  0.0  0.0  
0.0  0.0  2.0  0.0  0.0  0.0  
0.0  0.0  0.0  0.0  0.0  0.0  
c:\Users\luizh\Desktop\estagio\notebooks\casting\dataset\test\images\cast_def_0_4616_jpeg.rf.07e5761410e9d4a75f29ebc7497ef519.jpg
Elapsed time = 8.31294560432434
[('burr', 99.99514818191528), ('crack', 87.1674120426178)]
[{'class': 'burr', 'x1': 40, 'x2': 589, 'y1': 30, 'y2': 613}, {'class': 'crack', 'x1': 226, 'x2': 304, 'y1': 466, 'y2': 537}]
[0.9238065779948454, 0.5547128926408968]
2.0  0.0  0.0  0.0  0.0  0.0  
0.0  7.0  6.0  0.0  0.0  0.0  
0.0  1.0  9.0  0.0  0.0  0.0  
0.0  4.0  0.0  10.0  0.0  0.0  
0.0  0.0  2.0  0.0  0.0  0.0  
0.0  0.0  0.0  0.0  0.0  0.0  
c:\Users\luizh\Desktop\estagio\notebooks\casting\dataset\test\images\cast_def_0_4697_jpeg.rf.fd47a8ae48ce75afb06c05acc3845868.jpg
Elapsed time = 8.368446826934814
[('no_defect', 99.98974800109863), ('pit', 98.11526536941528), ('unpolished', 79.66395616531372)]
[{'class': 'pit', 'x1': 217, 'x2': 247, 'y1': 71, 'y2': 107}]
[0.41874578528742695]
2.0  0.0  0.0  0.0  0.0  0.0  
0.0  7.0  6.0  0.0  0.0  0.0  
0.0  1.0  10.0  0.0  0.0  0.0  
0.0  4.0  0.0  10.0  0.0  0.0  
0.0  0.0  2.0  0.0  0.0  0.0  
0.0  0.0  0.0  0.0  0.0  0.0  
c:\Users\luizh\Desktop\estagio\notebooks\casting\dataset\test\images\cast_def_0_4816_jpeg.rf.35462c80aaceac882a9101c44a3ad7a7.jpg
Elapsed time = 8.384777069091797
[('unpolished', 99.99687671661377), ('crack', 95.2098548412323)]
[{'class': 'crack', 'x1': 439, 'x2': 490, 'y1': 154, 'y2': 210}, {'class': 'unpolished', 'x1': 50, 'x2': 639, 'y1': 41, 'y2': 615}]
[0.7034482756599287, 0.9707857760901009]
2.0  0.0  0.0  0.0  0.0  0.0  
0.0  8.0  6.0  0.0  0.0  0.0  
0.0  1.0  10.0  0.0  0.0  0.0  
0.0  4.0  0.0  11.0  0.0  0.0  
0.0  0.0  2.0  0.0  0.0  0.0  
0.0  0.0  0.0  0.0  0.0  0.0  
c:\Users\luizh\Desktop\estagio\notebooks\casting\dataset\test\images\cast_def_0_4845_jpeg.rf.4aeeccaeceadde32548f7f4034b3b4b3.jpg
Elapsed time = 8.41597604751587
[('unpolished', 99.96248483657837), ('pit', 82.90368914604187)]
[{'class': 'unpolished', 'x1': 68, 'x2': 619, 'y1': 55, 'y2': 599}, {'class': 'pit', 'x1': 508, 'x2': 568, 'y1': 468, 'y2': 532}]
[0.9451601210796045, 0.7142857141085601]
2.0  0.0  0.0  0.0  0.0  0.0  
0.0  8.0  6.0  0.0  0.0  0.0  
0.0  1.0  11.0  0.0  0.0  0.0  
0.0  4.0  0.0  12.0  0.0  0.0  
0.0  0.0  2.0  0.0  0.0  0.0  
0.0  0.0  0.0  0.0  0.0  0.0  
c:\Users\luizh\Desktop\estagio\notebooks\casting\dataset\test\images\cast_def_0_4957_jpeg.rf.0dcd38b896d0cc5d2f4917751568b8b6.jpg
Elapsed time = 8.88934063911438
[('unpolished', 99.98643398284912)]
[{'class': 'crack', 'x1': 485, 'x2': 527, 'y1': 280, 'y2': 317}, {'class': 'unpolished', 'x1': 69, 'x2': 601, 'y1': 39, 'y2': 594}]
[0.0057484019886151, 0.958977825490215]
2.0  0.0  0.0  0.0  0.0  0.0  
0.0  8.0  6.0  0.0  0.0  0.0  
0.0  1.0  11.0  0.0  0.0  0.0  
0.0  5.0  0.0  13.0  0.0  0.0  
0.0  0.0  2.0  0.0  0.0  0.0  
0.0  0.0  0.0  0.0  0.0  0.0  
c:\Users\luizh\Desktop\estagio\notebooks\casting\dataset\test\images\cast_def_0_5218_jpeg.rf.ec3c670f28e20a17aebe83461220c648.jpg
Elapsed time = 8.815964698791504
[('unpolished', 99.48515295982361), ('no_defect', 98.34275841712952), ('crack', 90.63897132873535), ('crack', 86.54475808143616)]
[{'class': 'crack', 'x1': 376, 'x2': 417, 'y1': 447, 'y2': 516}, {'class': 'crack', 'x1': 316, 'x2': 371, 'y1': 509, 'y2': 564}]
[0.30117748727436777, 0.6708687309753717]
2.0  0.0  0.0  0.0  0.0  0.0  
0.0  10.0  6.0  0.0  0.0  0.0  
0.0  1.0  11.0  0.0  0.0  0.0  
0.0  5.0  0.0  13.0  0.0  0.0  
0.0  0.0  2.0  0.0  0.0  0.0  
0.0  0.0  0.0  0.0  0.0  0.0  
c:\Users\luizh\Desktop\estagio\notebooks\casting\dataset\test\images\cast_def_0_5331_jpeg.rf.39e2612f156de01ef45fe61be9f83927.jpg
Elapsed time = 8.56656789779663
[('burr', 99.99918937683105), ('crack', 84.40319895744324)]
[{'class': 'burr', 'x1': 18, 'x2': 586, 'y1': 36, 'y2': 601}, {'class': 'crack', 'x1': 218, 'x2': 307, 'y1': 134, 'y2': 176}]
[0.9310270322150003, 0.2973094169736974]
3.0  0.0  0.0  0.0  0.0  0.0  
0.0  11.0  6.0  0.0  0.0  0.0  
0.0  1.0  11.0  0.0  0.0  0.0  
0.0  5.0  0.0  13.0  0.0  0.0  
0.0  0.0  2.0  0.0  0.0  0.0  
0.0  0.0  0.0  0.0  0.0  0.0  
c:\Users\luizh\Desktop\estagio\notebooks\casting\dataset\test\images\cast_def_0_5415_jpeg.rf.21c1da31ef1d981b1035472fcc2cfb2b.jpg
Elapsed time = 8.783255815505981
[('unpolished', 99.99698400497437), ('crack', 75.48781037330627)]
[{'class': 'unpolished', 'x1': 15, 'x2': 583, 'y1': 38, 'y2': 598}, {'class': 'crack', 'x1': 230, 'x2': 275, 'y1': 466, 'y2': 517}]
[0.9303822937596504, 0.6278434938951036]
3.0  0.0  0.0  0.0  0.0  0.0  
0.0  12.0  6.0  0.0  0.0  0.0  
0.0  1.0  11.0  0.0  0.0  0.0  
0.0  5.0  0.0  14.0  0.0  0.0  
0.0  0.0  2.0  0.0  0.0  0.0  
0.0  0.0  0.0  0.0  0.0  0.0  
c:\Users\luizh\Desktop\estagio\notebooks\casting\dataset\test\images\cast_def_0_5480_jpeg.rf.f5a591a5b6fc81a7fae7ce8ed2c159c9.jpg
Elapsed time = 9.797133207321167
[('no_defect', 99.97054934501648), ('crack', 91.09949469566345)]
[{'class': 'crack', 'x1': 263, 'x2': 306, 'y1': 35, 'y2': 76}]
[0.6602918970003563]
3.0  0.0  0.0  0.0  0.0  0.0  
0.0  13.0  6.0  0.0  0.0  0.0  
0.0  1.0  11.0  0.0  0.0  0.0  
0.0  5.0  0.0  14.0  0.0  0.0  
0.0  0.0  2.0  0.0  0.0  0.0  
0.0  0.0  0.0  0.0  0.0  0.0  
c:\Users\luizh\Desktop\estagio\notebooks\casting\dataset\test\images\cast_def_0_5487_jpeg.rf.13ed6c5f195a7d9d056a4f63e4242fa5.jpg
Elapsed time = 9.07644534111023
[('unpolished', 99.9883770942688), ('crack', 90.76836705207825), ('crack', 84.88922715187073)]
[{'class': 'unpolished', 'x1': 70, 'x2': 597, 'y1': 59, 'y2': 592}, {'class': 'crack', 'x1': 366, 'x2': 461, 'y1': 91, 'y2': 200}]
[0.9624231463415972, 0.7022180273051233]
3.0  0.0  0.0  0.0  0.0  0.0  
0.0  14.0  6.0  0.0  0.0  0.0  
0.0  1.0  11.0  0.0  0.0  0.0  
0.0  5.0  0.0  15.0  0.0  0.0  
0.0  0.0  2.0  0.0  0.0  0.0  
0.0  0.0  0.0  0.0  0.0  0.0  
c:\Users\luizh\Desktop\estagio\notebooks\casting\dataset\test\images\cast_def_0_5574_jpeg.rf.b9f1b3ae5b953c4a6f64b2436ee942a8.jpg
Elapsed time = 8.62534236907959
[('unpolished', 99.99542236328125), ('crack', 91.21724367141724)]
[{'class': 'crack', 'x1': 488, 'x2': 536, 'y1': 193, 'y2': 338}, {'class': 'unpolished', 'x1': 47, 'x2': 591, 'y1': 68, 'y2': 604}]
[0.7371134019826983, 0.9531895364814095]
3.0  0.0  0.0  0.0  0.0  0.0  
0.0  15.0  6.0  0.0  0.0  0.0  
0.0  1.0  11.0  0.0  0.0  0.0  
0.0  5.0  0.0  16.0  0.0  0.0  
0.0  0.0  2.0  0.0  0.0  0.0  
0.0  0.0  0.0  0.0  0.0  0.0  
c:\Users\luizh\Desktop\estagio\notebooks\casting\dataset\test\images\cast_def_0_5583_jpeg.rf.891ff56975d185acdf1b72c0bae47631.jpg
Elapsed time = 8.556073427200317
[('unpolished', 99.99879598617554)]
[{'class': 'crack', 'x1': 445, 'x2': 486, 'y1': 212, 'y2': 253}, {'class': 'unpolished', 'x1': 54, 'x2': 582, 'y1': 51, 'y2': 583}]
[0.006619361139086837, 0.9517335146125377]
3.0  0.0  0.0  0.0  0.0  0.0  
0.0  15.0  6.0  0.0  0.0  0.0  
0.0  1.0  11.0  0.0  0.0  0.0  
0.0  6.0  0.0  17.0  0.0  0.0  
0.0  0.0  2.0  0.0  0.0  0.0  
0.0  0.0  0.0  0.0  0.0  0.0  
c:\Users\luizh\Desktop\estagio\notebooks\casting\dataset\test\images\cast_def_0_5768_jpeg.rf.81e8aac5bdd2ad52a12a2c74a47e403c.jpg
Elapsed time = 8.966673851013184
[('unpolished', 99.15856122970581), ('no_defect', 99.44646954536438), ('crack', 77.24400162696838)]
[{'class': 'crack', 'x1': 285, 'x2': 313, 'y1': 127, 'y2': 160}]
[0.48192771055305555]
3.0  0.0  0.0  0.0  0.0  0.0  
0.0  16.0  6.0  0.0  0.0  0.0  
0.0  1.0  11.0  0.0  0.0  0.0  
0.0  6.0  0.0  17.0  0.0  0.0  
0.0  0.0  2.0  0.0  0.0  0.0  
0.0  0.0  0.0  0.0  0.0  0.0  
c:\Users\luizh\Desktop\estagio\notebooks\casting\dataset\test\images\cast_def_0_588_jpeg.rf.98ff124fdf20d0cc0019b2b1c3ad3681.jpg
Elapsed time = 9.304149389266968
[('no_defect', 99.88086223602295), ('unpolished', 99.1112768650055)]
[{'class': 'crack', 'x1': 386, 'x2': 419, 'y1': 158, 'y2': 188}]
[0.004024128511950344]
3.0  0.0  0.0  0.0  0.0  0.0  
0.0  16.0  6.0  0.0  0.0  0.0  
0.0  1.0  11.0  0.0  0.0  0.0  
0.0  7.0  0.0  17.0  0.0  0.0  
0.0  0.0  2.0  0.0  0.0  0.0  
0.0  0.0  0.0  0.0  0.0  0.0  
c:\Users\luizh\Desktop\estagio\notebooks\casting\dataset\test\images\cast_def_0_598_jpeg.rf.c8190bacd7274f4a437dbb5066093389.jpg
Elapsed time = 8.743203163146973
[('burr', 99.99903440475464), ('crack', 94.19756531715393)]
[{'class': 'burr', 'x1': 47, 'x2': 600, 'y1': 54, 'y2': 611}, {'class': 'crack', 'x1': 486, 'x2': 521, 'y1': 299, 'y2': 375}]
[0.9613122773064211, 0.6414662082928219]
4.0  0.0  0.0  0.0  0.0  0.0  
0.0  17.0  6.0  0.0  0.0  0.0  
0.0  1.0  11.0  0.0  0.0  0.0  
0.0  7.0  0.0  17.0  0.0  0.0  
0.0  0.0  2.0  0.0  0.0  0.0  
0.0  0.0  0.0  0.0  0.0  0.0  
c:\Users\luizh\Desktop\estagio\notebooks\casting\dataset\test\images\cast_def_0_6023_jpeg.rf.b3493c51bfc53f9835a16baba7491c81.jpg
Elapsed time = 8.404489040374756
[('unpolished', 99.98711347579956), ('crack', 94.99355554580688), ('crack', 89.46502804756165), ('crack', 77.07701325416565)]
[{'class': 'crack', 'x1': 144, 'x2': 205, 'y1': 378, 'y2': 523}]
[0.6582824667798061]
4.0  0.0  0.0  0.0  0.0  0.0  
0.0  18.0  6.0  0.0  0.0  0.0  
0.0  1.0  11.0  0.0  0.0  0.0  
0.0  7.0  0.0  17.0  0.0  0.0  
0.0  0.0  2.0  0.0  0.0  0.0  
0.0  0.0  0.0  0.0  0.0  0.0  
c:\Users\luizh\Desktop\estagio\notebooks\casting\dataset\test\images\cast_def_0_6103_jpeg.rf.312d3d7c054351a5328a998968ab2e6d.jpg
Elapsed time = 8.311568021774292
[('burr', 99.99884366989136), ('crack', 80.53614497184753)]
[{'class': 'burr', 'x1': 33, 'x2': 580, 'y1': 43, 'y2': 607}, {'class': 'crack', 'x1': 281, 'x2': 354, 'y1': 483, 'y2': 518}]
[0.9310358240274773, 0.5979381441430996]
5.0  0.0  0.0  0.0  0.0  0.0  
0.0  19.0  6.0  0.0  0.0  0.0  
0.0  1.0  11.0  0.0  0.0  0.0  
0.0  7.0  0.0  17.0  0.0  0.0  
0.0  0.0  2.0  0.0  0.0  0.0  
0.0  0.0  0.0  0.0  0.0  0.0  
c:\Users\luizh\Desktop\estagio\notebooks\casting\dataset\test\images\cast_def_0_6426_jpeg.rf.53015b0ee6a895aa8c168133f33efbb9.jpg
Elapsed time = 8.156569957733154
[('unpolished', 99.98961687088013), ('crack', 98.06751608848572)]
[{'class': 'pit', 'x1': 110, 'x2': 142, 'y1': 294, 'y2': 333}, {'class': 'unpolished', 'x1': 41, 'x2': 573, 'y1': 45, 'y2': 592}]
[0.724907062747889, 0.9541601892499014]
5.0  0.0  0.0  0.0  0.0  0.0  
0.0  19.0  7.0  0.0  0.0  0.0  
0.0  1.0  11.0  0.0  0.0  0.0  
0.0  7.0  0.0  18.0  0.0  0.0  
0.0  0.0  2.0  0.0  0.0  0.0  
0.0  0.0  0.0  0.0  0.0  0.0  
c:\Users\luizh\Desktop\estagio\notebooks\casting\dataset\test\images\cast_def_0_6831_jpeg.rf.343571e515a7153e7e0319f1780b003e.jpg
Elapsed time = 8.290318727493286
[('unpolished', 99.9734103679657), ('crack', 78.40473651885986)]
[{'class': 'unpolished', 'x1': 48, 'x2': 579, 'y1': 63, 'y2': 593}, {'class': 'crack', 'x1': 185, 'x2': 232, 'y1': 440, 'y2': 474}]
[0.990598017265428, 0.5147515525952052]
5.0  0.0  0.0  0.0  0.0  0.0  
0.0  20.0  7.0  0.0  0.0  0.0  
0.0  1.0  11.0  0.0  0.0  0.0  
0.0  7.0  0.0  19.0  0.0  0.0  
0.0  0.0  2.0  0.0  0.0  0.0  
0.0  0.0  0.0  0.0  0.0  0.0  
c:\Users\luizh\Desktop\estagio\notebooks\casting\dataset\test\images\cast_def_0_7041_jpeg.rf.4311cb1f3bdac8f849d7716b0eb66c01.jpg
Elapsed time = 8.30089545249939
[('unpolished', 99.93563294410706), ('crack', 88.74451518058777), ('crack', 71.39521837234497)]
[{'class': 'pit', 'x1': 232, 'x2': 267, 'y1': 451, 'y2': 476}, {'class': 'pit', 'x1': 396, 'x2': 428, 'y1': 449, 'y2': 481}]
[0.42724609354138376, 0.7355932197155989]
5.0  0.0  0.0  0.0  0.0  0.0  
0.0  20.0  9.0  0.0  0.0  0.0  
0.0  1.0  11.0  0.0  0.0  0.0  
0.0  7.0  0.0  19.0  0.0  0.0  
0.0  0.0  2.0  0.0  0.0  0.0  
0.0  0.0  0.0  0.0  0.0  0.0  
c:\Users\luizh\Desktop\estagio\notebooks\casting\dataset\test\images\cast_def_0_7474_jpeg.rf.7263e9141df421301e4e70bf9a428908.jpg
Elapsed time = 8.494083404541016
[('unpolished', 99.93589520454407), ('pit', 89.45179581642151)]
[{'class': 'pit', 'x1': 204, 'x2': 249, 'y1': 63, 'y2': 124}]
[0.6520164209968566]
5.0  0.0  0.0  0.0  0.0  0.0  
0.0  20.0  9.0  0.0  0.0  0.0  
0.0  1.0  12.0  0.0  0.0  0.0  
0.0  7.0  0.0  19.0  0.0  0.0  
0.0  0.0  2.0  0.0  0.0  0.0  
0.0  0.0  0.0  0.0  0.0  0.0  
c:\Users\luizh\Desktop\estagio\notebooks\casting\dataset\test\images\cast_def_0_7576_jpeg.rf.8918d0307c239e406241989d54400189.jpg
Elapsed time = 8.322604417800903
[('no_defect', 99.99933242797852), ('crack', 77.21702456474304)]
[{'class': 'pit', 'x1': 129, 'x2': 169, 'y1': 571, 'y2': 619}]
[0.5882352938473183]
5.0  0.0  0.0  0.0  0.0  0.0  
0.0  20.0  10.0  0.0  0.0  0.0  
0.0  1.0  12.0  0.0  0.0  0.0  
0.0  7.0  0.0  19.0  0.0  0.0  
0.0  0.0  2.0  0.0  0.0  0.0  
0.0  0.0  0.0  0.0  0.0  0.0  
c:\Users\luizh\Desktop\estagio\notebooks\casting\dataset\test\images\cast_def_0_7684_jpeg.rf.653f894f0e7bf104573551e68ca90c18.jpg
Elapsed time = 8.372758865356445
[('unpolished', 99.99421834945679), ('crack', 93.06160807609558)]
[{'class': 'crack', 'x1': 148, 'x2': 189, 'y1': 219, 'y2': 303}, {'class': 'unpolished', 'x1': 74, 'x2': 555, 'y1': 36, 'y2': 588}]
[0.6567505719153952, 0.9635738225401174]
5.0  0.0  0.0  0.0  0.0  0.0  
0.0  21.0  10.0  0.0  0.0  0.0  
0.0  1.0  12.0  0.0  0.0  0.0  
0.0  7.0  0.0  20.0  0.0  0.0  
0.0  0.0  2.0  0.0  0.0  0.0  
0.0  0.0  0.0  0.0  0.0  0.0  
c:\Users\luizh\Desktop\estagio\notebooks\casting\dataset\test\images\cast_def_0_7722_jpeg.rf.106071b7c05b7fdeeaf5698d32f672a1.jpg
Elapsed time = 8.787657499313354
[('unpolished', 99.83696341514587), ('crack', 84.47473645210266)]
[{'class': 'crack', 'x1': 171, 'x2': 193, 'y1': 245, 'y2': 287}, {'class': 'crack', 'x1': 416, 'x2': 457, 'y1': 427, 'y2': 468}]
[0.003931781045734903, 0.6091612132009748]
5.0  0.0  0.0  0.0  0.0  0.0  
0.0  22.0  10.0  0.0  0.0  0.0  
0.0  1.0  12.0  0.0  0.0  0.0  
0.0  8.0  0.0  20.0  0.0  0.0  
0.0  0.0  2.0  0.0  0.0  0.0  
0.0  0.0  0.0  0.0  0.0  0.0  
c:\Users\luizh\Desktop\estagio\notebooks\casting\dataset\test\images\cast_def_0_8451_jpeg.rf.191d37264f43b30c9694448c20ae1ac7.jpg
Elapsed time = 8.65564227104187
[('unpolished', 99.97712969779968), ('crack', 94.25821900367737), ('no_defect', 74.34601187705994)]
[{'class': 'crack', 'x1': 319, 'x2': 352, 'y1': 146, 'y2': 171}]
[0.7626310764893888]
5.0  0.0  0.0  0.0  0.0  0.0  
0.0  23.0  10.0  0.0  0.0  0.0  
0.0  1.0  12.0  0.0  0.0  0.0  
0.0  8.0  0.0  20.0  0.0  0.0  
0.0  0.0  2.0  0.0  0.0  0.0  
0.0  0.0  0.0  0.0  0.0  0.0  
c:\Users\luizh\Desktop\estagio\notebooks\casting\dataset\test\images\cast_def_0_8452_jpeg.rf.1634d793340ce8be9e63f09e09e220b4.jpg
Elapsed time = 8.920108795166016
[('unpolished', 99.98666048049927), ('pit', 99.27259683609009)]
[{'class': 'crack', 'x1': 529, 'x2': 577, 'y1': 182, 'y2': 233}]
[0.7675312197350205]
5.0  0.0  0.0  0.0  0.0  0.0  
0.0  23.0  10.0  0.0  0.0  0.0  
0.0  2.0  12.0  0.0  0.0  0.0  
0.0  8.0  0.0  20.0  0.0  0.0  
0.0  0.0  2.0  0.0  0.0  0.0  
0.0  0.0  0.0  0.0  0.0  0.0  
c:\Users\luizh\Desktop\estagio\notebooks\casting\dataset\test\images\cast_def_0_8631_jpeg.rf.6e312f5c574d099ca1d02746d6e90b79.jpg
Elapsed time = 8.551658630371094
[('unpolished', 99.94819760322571), ('pit', 99.22903180122375)]
[{'class': 'unpolished', 'x1': 55, 'x2': 587, 'y1': 51, 'y2': 591}, {'class': 'pit', 'x1': 411, 'x2': 449, 'y1': 460, 'y2': 509}]
[0.9555936514925772, 0.549946294011844]
5.0  0.0  0.0  0.0  0.0  0.0  
0.0  23.0  10.0  0.0  0.0  0.0  
0.0  2.0  13.0  0.0  0.0  0.0  
0.0  8.0  0.0  21.0  0.0  0.0  
0.0  0.0  2.0  0.0  0.0  0.0  
0.0  0.0  0.0  0.0  0.0  0.0  
c:\Users\luizh\Desktop\estagio\notebooks\casting\dataset\test\images\cast_def_0_8711_jpeg.rf.423d3f0d5ed2c1f8c500d2b2a75eed99.jpg
Elapsed time = 8.507241010665894
[('burr', 99.99842643737793), ('crack', 98.0467438697815), ('crack', 97.16706871986389)]
[{'class': 'burr', 'x1': 91, 'x2': 541, 'y1': 61, 'y2': 573}, {'class': 'crack', 'x1': 424, 'x2': 461, 'y1': 364, 'y2': 435}]
[0.9709951086891598, 0.7108976281264192]
6.0  0.0  0.0  0.0  0.0  0.0  
0.0  24.0  10.0  0.0  0.0  0.0  
0.0  2.0  13.0  0.0  0.0  0.0  
0.0  8.0  0.0  21.0  0.0  0.0  
0.0  0.0  2.0  0.0  0.0  0.0  
0.0  0.0  0.0  0.0  0.0  0.0  
c:\Users\luizh\Desktop\estagio\notebooks\casting\dataset\test\images\cast_def_0_9008_jpeg.rf.cd7fbfe83217d6af0b6c3ebd919a83ec.jpg
Elapsed time = 9.115955829620361
[('unpolished', 99.97528195381165), ('crack', 79.24700975418091)]
[{'class': 'crack', 'x1': 470, 'x2': 509, 'y1': 239, 'y2': 280}]
[0.4645449466976298]
6.0  0.0  0.0  0.0  0.0  0.0  
0.0  25.0  10.0  0.0  0.0  0.0  
0.0  2.0  13.0  0.0  0.0  0.0  
0.0  8.0  0.0  21.0  0.0  0.0  
0.0  0.0  2.0  0.0  0.0  0.0  
0.0  0.0  0.0  0.0  0.0  0.0  
c:\Users\luizh\Desktop\estagio\notebooks\casting\dataset\test\images\cast_def_0_9088_jpeg.rf.4a6395876c558990463891ff505fb17b.jpg
Elapsed time = 8.132098913192749
[('unpolished', 99.96414184570312)]
[{'class': 'crack', 'x1': 470, 'x2': 507, 'y1': 259, 'y2': 359}]
[0.015055338541605406]
6.0  0.0  0.0  0.0  0.0  0.0  
0.0  25.0  10.0  0.0  0.0  0.0  
0.0  2.0  13.0  0.0  0.0  0.0  
0.0  9.0  0.0  21.0  0.0  0.0  
0.0  0.0  2.0  0.0  0.0  0.0  
0.0  0.0  0.0  0.0  0.0  0.0  
c:\Users\luizh\Desktop\estagio\notebooks\casting\dataset\test\images\cast_def_0_910_jpeg.rf.10258b34d1c95226638cdbbbbd6b2753.jpg
Elapsed time = 8.468226909637451
[('unpolished', 99.98385906219482), ('pit', 94.97973322868347)]
[{'class': 'unpolished', 'x1': 58, 'x2': 604, 'y1': 42, 'y2': 593}, {'class': 'pit', 'x1': 529, 'x2': 578, 'y1': 423, 'y2': 485}]
[0.9627665436974036, 0.7808219175806407]
6.0  0.0  0.0  0.0  0.0  0.0  
0.0  25.0  10.0  0.0  0.0  0.0  
0.0  2.0  14.0  0.0  0.0  0.0  
0.0  9.0  0.0  22.0  0.0  0.0  
0.0  0.0  2.0  0.0  0.0  0.0  
0.0  0.0  0.0  0.0  0.0  0.0  
c:\Users\luizh\Desktop\estagio\notebooks\casting\dataset\test\images\cast_def_0_9328_jpeg.rf.35ef19a7cf561d3342ccb25abdedb230.jpg
Elapsed time = 8.371323347091675
[('burr', 99.98268485069275), ('crack', 96.32092714309692)]
[{'class': 'crack', 'x1': 379, 'x2': 431, 'y1': 112, 'y2': 177}, {'class': 'burr', 'x1': 71, 'x2': 598, 'y1': 23, 'y2': 615}]
[0.8734030194908818, 0.9496228039056579]
7.0  0.0  0.0  0.0  0.0  0.0  
0.0  26.0  10.0  0.0  0.0  0.0  
0.0  2.0  14.0  0.0  0.0  0.0  
0.0  9.0  0.0  22.0  0.0  0.0  
0.0  0.0  2.0  0.0  0.0  0.0  
0.0  0.0  0.0  0.0  0.0  0.0  
c:\Users\luizh\Desktop\estagio\notebooks\casting\dataset\test\images\cast_def_0_9356_jpeg.rf.057f1244bd635f63c36b5bf3a2f4b74c.jpg
Elapsed time = 8.333720207214355
[('no_defect', 99.99526739120483), ('crack', 99.46550130844116)]
[{'class': 'crack', 'x1': 78, 'x2': 143, 'y1': 513, 'y2': 572}]
[0.8820598004551352]
7.0  0.0  0.0  0.0  0.0  0.0  
0.0  27.0  10.0  0.0  0.0  0.0  
0.0  2.0  14.0  0.0  0.0  0.0  
0.0  9.0  0.0  22.0  0.0  0.0  
0.0  0.0  2.0  0.0  0.0  0.0  
0.0  0.0  0.0  0.0  0.0  0.0  
c:\Users\luizh\Desktop\estagio\notebooks\casting\dataset\test\images\cast_def_0_9393_jpeg.rf.1b71214587af97209abc9dda13642076.jpg
Elapsed time = 8.412806510925293
[('unpolished', 99.97444748878479), ('crack', 84.70988273620605), ('crack', 70.01131176948547)]
[{'class': 'unpolished', 'x1': 56, 'x2': 583, 'y1': 68, 'y2': 610}, {'class': 'crack', 'x1': 279, 'x2': 430, 'y1': 489, 'y2': 558}]
[0.9464419501846894, 0.6607460034965114]
7.0  0.0  0.0  0.0  0.0  0.0  
0.0  28.0  10.0  0.0  0.0  0.0  
0.0  2.0  14.0  0.0  0.0  0.0  
0.0  9.0  0.0  23.0  0.0  0.0  
0.0  0.0  2.0  0.0  0.0  0.0  
0.0  0.0  0.0  0.0  0.0  0.0  
c:\Users\luizh\Desktop\estagio\notebooks\casting\dataset\test\images\cast_def_0_9496_jpeg.rf.6943ee0bc23af426c570a926f742c6bb.jpg
Elapsed time = 8.477964639663696
[('burr', 99.99877214431763), ('pit', 98.02430272102356), ('crack', 78.3645749092102)]
[{'class': 'burr', 'x1': 55, 'x2': 597, 'y1': 51, 'y2': 595}, {'class': 'crack', 'x1': 294, 'x2': 375, 'y1': 471, 'y2': 532}, {'class': 'pit', 'x1': 257, 'x2': 315, 'y1': 88, 'y2': 143}]
[0.9455176904678155, 0.6342825236117099, 0.5819176502787453]
8.0  0.0  0.0  0.0  0.0  0.0  
0.0  29.0  10.0  0.0  0.0  0.0  
0.0  2.0  15.0  0.0  0.0  0.0  
0.0  9.0  0.0  23.0  0.0  0.0  
0.0  0.0  2.0  0.0  0.0  0.0  
0.0  0.0  0.0  0.0  0.0  0.0  
c:\Users\luizh\Desktop\estagio\notebooks\casting\dataset\test\images\cast_def_0_9736_jpeg.rf.443ad77121f3ed52e564dc9b04c87704.jpg
Elapsed time = 8.379381656646729
[('burr', 99.99902248382568), ('pit', 98.67970943450928)]
[{'class': 'burr', 'x1': 39, 'x2': 601, 'y1': 39, 'y2': 599}]
[0.9444444444414793]
9.0  0.0  0.0  0.0  0.0  0.0  
0.0  29.0  10.0  0.0  0.0  0.0  
0.0  2.0  15.0  0.0  0.0  0.0  
0.0  9.0  0.0  23.0  0.0  0.0  
0.0  0.0  2.0  0.0  0.0  0.0  
0.0  0.0  0.0  0.0  0.0  0.0  
c:\Users\luizh\Desktop\estagio\notebooks\casting\dataset\test\images\cast_def_0_9762_jpeg.rf.5f38b954156e3df563a826cd37dbca19.jpg
Elapsed time = 8.426752090454102
[('no_defect', 94.18851137161255), ('unpolished', 99.94990825653076), ('crack', 86.22359037399292)]
[{'class': 'unpolished', 'x1': 10, 'x2': 576, 'y1': 47, 'y2': 601}, {'class': 'crack', 'x1': 192, 'x2': 247, 'y1': 41, 'y2': 113}]
[0.9754192337220917, 0.7760141091763637]
9.0  0.0  0.0  0.0  0.0  0.0  
0.0  30.0  10.0  0.0  0.0  0.0  
0.0  2.0  15.0  0.0  0.0  0.0  
0.0  9.0  0.0  23.0  0.0  0.0  
0.0  0.0  2.0  1.0  0.0  0.0  
0.0  0.0  0.0  0.0  0.0  0.0  
c:\Users\luizh\Desktop\estagio\notebooks\casting\dataset\test\images\cast_def_0_9872_jpeg.rf.0617ce234268ed44f997fca0c938820b.jpg
Elapsed time = 8.409499883651733
[('unpolished', 99.94962215423584), ('pit', 98.65037202835083), ('crack', 89.39314484596252), ('crack', 70.11600136756897)]
[{'class': 'pit', 'x1': 195, 'x2': 236, 'y1': 515, 'y2': 592}]
[0.7278779470935152]
9.0  0.0  0.0  0.0  0.0  0.0  
0.0  30.0  10.0  0.0  0.0  0.0  
0.0  2.0  16.0  0.0  0.0  0.0  
0.0  9.0  0.0  23.0  0.0  0.0  
0.0  0.0  2.0  1.0  0.0  0.0  
0.0  0.0  0.0  0.0  0.0  0.0  
c:\Users\luizh\Desktop\estagio\notebooks\casting\dataset\test\images\cast_ok_0_1192_jpeg.rf.1c315c4ccf9282aaa8e05451a2e4865f.jpg
Elapsed time = 8.359366178512573
[('no_defect', 99.99966621398926)]
[{'class': 'no_defect', 'x1': 56, 'x2': 579, 'y1': 43, 'y2': 577}]
[0.9684451122693402]
9.0  0.0  0.0  0.0  0.0  0.0  
0.0  30.0  10.0  0.0  0.0  0.0  
0.0  2.0  16.0  0.0  0.0  0.0  
0.0  9.0  0.0  23.0  0.0  0.0  
0.0  0.0  2.0  1.0  1.0  0.0  
0.0  0.0  0.0  0.0  0.0  0.0  
c:\Users\luizh\Desktop\estagio\notebooks\casting\dataset\test\images\cast_ok_0_1469_jpeg.rf.4ce2a4eb4fb79024d5f31e3fb3f5b252.jpg
Elapsed time = 8.176268577575684
[('no_defect', 99.77585077285767)]
[{'class': 'no_defect', 'x1': 29, 'x2': 616, 'y1': 26, 'y2': 628}]
[0.9654240317194006]
9.0  0.0  0.0  0.0  0.0  0.0  
0.0  30.0  10.0  0.0  0.0  0.0  
0.0  2.0  16.0  0.0  0.0  0.0  
0.0  9.0  0.0  23.0  0.0  0.0  
0.0  0.0  2.0  1.0  2.0  0.0  
0.0  0.0  0.0  0.0  0.0  0.0  
c:\Users\luizh\Desktop\estagio\notebooks\casting\dataset\test\images\cast_ok_0_1682_jpeg.rf.6497661599ee2914d4814ac219e87f83.jpg
Elapsed time = 8.728468179702759
[('no_defect', 99.99972581863403)]
[{'class': 'no_defect', 'x1': 34, 'x2': 581, 'y1': 51, 'y2': 592}]
[0.9713990283581558]
9.0  0.0  0.0  0.0  0.0  0.0  
0.0  30.0  10.0  0.0  0.0  0.0  
0.0  2.0  16.0  0.0  0.0  0.0  
0.0  9.0  0.0  23.0  0.0  0.0  
0.0  0.0  2.0  1.0  3.0  0.0  
0.0  0.0  0.0  0.0  0.0  0.0  
c:\Users\luizh\Desktop\estagio\notebooks\casting\dataset\test\images\cast_ok_0_1723_jpeg.rf.4f638ec79a4e6b0117735daa532c0419.jpg
Elapsed time = 8.59873080253601
[('unpolished', 99.99266862869263)]
[{'class': 'unpolished', 'x1': 41, 'x2': 587, 'y1': 77, 'y2': 605}]
[0.9488392562405489]
9.0  0.0  0.0  0.0  0.0  0.0  
0.0  30.0  10.0  0.0  0.0  0.0  
0.0  2.0  16.0  0.0  0.0  0.0  
0.0  9.0  0.0  24.0  0.0  0.0  
0.0  0.0  2.0  1.0  3.0  0.0  
0.0  0.0  0.0  0.0  0.0  0.0  
c:\Users\luizh\Desktop\estagio\notebooks\casting\dataset\test\images\cast_ok_0_1817_jpeg.rf.744d6f944190153ec59d19edb7df6225.jpg
Elapsed time = 8.563175916671753
[('no_defect', 99.9996542930603)]
[{'class': 'no_defect', 'x1': 33, 'x2': 608, 'y1': 11, 'y2': 577}]
[0.9876997638078964]
9.0  0.0  0.0  0.0  0.0  0.0  
0.0  30.0  10.0  0.0  0.0  0.0  
0.0  2.0  16.0  0.0  0.0  0.0  
0.0  9.0  0.0  24.0  0.0  0.0  
0.0  0.0  2.0  1.0  4.0  0.0  
0.0  0.0  0.0  0.0  0.0  0.0  
c:\Users\luizh\Desktop\estagio\notebooks\casting\dataset\test\images\cast_ok_0_1863_jpeg.rf.93d19a76c59a8862a739a018e12426b4.jpg
Elapsed time = 8.80272102355957
[('no_defect', 99.99840259552002)]
[{'class': 'no_defect', 'x1': 81, 'x2': 606, 'y1': 17, 'y2': 618}]
[0.9828704395902398]
9.0  0.0  0.0  0.0  0.0  0.0  
0.0  30.0  10.0  0.0  0.0  0.0  
0.0  2.0  16.0  0.0  0.0  0.0  
0.0  9.0  0.0  24.0  0.0  0.0  
0.0  0.0  2.0  1.0  5.0  0.0  
0.0  0.0  0.0  0.0  0.0  0.0  
c:\Users\luizh\Desktop\estagio\notebooks\casting\dataset\test\images\cast_ok_0_196_jpeg.rf.c7353455814c5b74373984a64a84764b.jpg
Elapsed time = 8.456951379776001
[('no_defect', 99.99909400939941)]
[{'class': 'no_defect', 'x1': 30, 'x2': 597, 'y1': 75, 'y2': 582}]
[0.956695399843111]
9.0  0.0  0.0  0.0  0.0  0.0  
0.0  30.0  10.0  0.0  0.0  0.0  
0.0  2.0  16.0  0.0  0.0  0.0  
0.0  9.0  0.0  24.0  0.0  0.0  
0.0  0.0  2.0  1.0  6.0  0.0  
0.0  0.0  0.0  0.0  0.0  0.0  
c:\Users\luizh\Desktop\estagio\notebooks\casting\dataset\test\images\cast_ok_0_2235_jpeg.rf.21bc991de11d3d28a1ba0f9ad4565762.jpg
Elapsed time = 8.404439210891724
[('no_defect', 99.99926090240479)]
[{'class': 'no_defect', 'x1': 42, 'x2': 579, 'y1': 67, 'y2': 615}]
[0.9625164664053247]
9.0  0.0  0.0  0.0  0.0  0.0  
0.0  30.0  10.0  0.0  0.0  0.0  
0.0  2.0  16.0  0.0  0.0  0.0  
0.0  9.0  0.0  24.0  0.0  0.0  
0.0  0.0  2.0  1.0  7.0  0.0  
0.0  0.0  0.0  0.0  0.0  0.0  
c:\Users\luizh\Desktop\estagio\notebooks\casting\dataset\test\images\cast_ok_0_2541_jpeg.rf.a6156eee89037f3eeecc12bfd649ccf4.jpg
Elapsed time = 8.55710506439209
[('no_defect', 99.9995231628418)]
[{'class': 'no_defect', 'x1': 61, 'x2': 624, 'y1': 29, 'y2': 623}]
[0.9608249577564469]
9.0  0.0  0.0  0.0  0.0  0.0  
0.0  30.0  10.0  0.0  0.0  0.0  
0.0  2.0  16.0  0.0  0.0  0.0  
0.0  9.0  0.0  24.0  0.0  0.0  
0.0  0.0  2.0  1.0  8.0  0.0  
0.0  0.0  0.0  0.0  0.0  0.0  
c:\Users\luizh\Desktop\estagio\notebooks\casting\dataset\test\images\cast_ok_0_2999_jpeg.rf.66db9903d6db0bb19261bb0e34897329.jpg
Elapsed time = 8.364010572433472
[('no_defect', 99.99958276748657)]
[{'class': 'no_defect', 'x1': 1, 'x2': 623, 'y1': 23, 'y2': 593}]
[0.9829799525588869]
9.0  0.0  0.0  0.0  0.0  0.0  
0.0  30.0  10.0  0.0  0.0  0.0  
0.0  2.0  16.0  0.0  0.0  0.0  
0.0  9.0  0.0  24.0  0.0  0.0  
0.0  0.0  2.0  1.0  9.0  0.0  
0.0  0.0  0.0  0.0  0.0  0.0  
c:\Users\luizh\Desktop\estagio\notebooks\casting\dataset\test\images\cast_ok_0_305_jpeg.rf.658b0c6e9e3aa598a844c0eefa1969cc.jpg
Elapsed time = 8.311931133270264
[('no_defect', 99.99958276748657)]
[{'class': 'no_defect', 'x1': 39, 'x2': 628, 'y1': 34, 'y2': 618}]
[0.9650012622467898]
9.0  0.0  0.0  0.0  0.0  0.0  
0.0  30.0  10.0  0.0  0.0  0.0  
0.0  2.0  16.0  0.0  0.0  0.0  
0.0  9.0  0.0  24.0  0.0  0.0  
0.0  0.0  2.0  1.0  10.0  0.0  
0.0  0.0  0.0  0.0  0.0  0.0  
c:\Users\luizh\Desktop\estagio\notebooks\casting\dataset\test\images\cast_ok_0_3337_jpeg.rf.1cef123b6e628068a726afa623a0d87c.jpg
Elapsed time = 8.208865404129028
[('no_defect', 99.99836683273315)]
[{'class': 'no_defect', 'x1': 56, 'x2': 596, 'y1': 2, 'y2': 605}]
[0.9699140924847075]
9.0  0.0  0.0  0.0  0.0  0.0  
0.0  30.0  10.0  0.0  0.0  0.0  
0.0  2.0  16.0  0.0  0.0  0.0  
0.0  9.0  0.0  24.0  0.0  0.0  
0.0  0.0  2.0  1.0  11.0  0.0  
0.0  0.0  0.0  0.0  0.0  0.0  
c:\Users\luizh\Desktop\estagio\notebooks\casting\dataset\test\images\cast_ok_0_352_jpeg.rf.ac261f4bd733a96d880d8bf17019aa21.jpg
Elapsed time = 8.482226610183716
[('no_defect', 99.99909400939941)]
[{'class': 'no_defect', 'x1': 37, 'x2': 591, 'y1': 24, 'y2': 587}]
[0.9669580853144625]
9.0  0.0  0.0  0.0  0.0  0.0  
0.0  30.0  10.0  0.0  0.0  0.0  
0.0  2.0  16.0  0.0  0.0  0.0  
0.0  9.0  0.0  24.0  0.0  0.0  
0.0  0.0  2.0  1.0  12.0  0.0  
0.0  0.0  0.0  0.0  0.0  0.0  
c:\Users\luizh\Desktop\estagio\notebooks\casting\dataset\test\images\cast_ok_0_3596_jpeg.rf.682b58a2bdf4f9c2ece793b79983bd29.jpg
Elapsed time = 8.497205257415771
[('no_defect', 99.99943971633911)]
[{'class': 'no_defect', 'x1': 49, 'x2': 595, 'y1': 58, 'y2': 638}]
[0.9790791036024807]
9.0  0.0  0.0  0.0  0.0  0.0  
0.0  30.0  10.0  0.0  0.0  0.0  
0.0  2.0  16.0  0.0  0.0  0.0  
0.0  9.0  0.0  24.0  0.0  0.0  
0.0  0.0  2.0  1.0  13.0  0.0  
0.0  0.0  0.0  0.0  0.0  0.0  
c:\Users\luizh\Desktop\estagio\notebooks\casting\dataset\test\images\cast_ok_0_3725_jpeg.rf.b4641eb723bf1c6f33d3844a0064128f.jpg
Elapsed time = 9.11566424369812
[('no_defect', 99.98065829277039)]
[{'class': 'no_defect', 'x1': 57, 'x2': 591, 'y1': 49, 'y2': 599}]
[0.9707908851244837]
9.0  0.0  0.0  0.0  0.0  0.0  
0.0  30.0  10.0  0.0  0.0  0.0  
0.0  2.0  16.0  0.0  0.0  0.0  
0.0  9.0  0.0  24.0  0.0  0.0  
0.0  0.0  2.0  1.0  14.0  0.0  
0.0  0.0  0.0  0.0  0.0  0.0  
c:\Users\luizh\Desktop\estagio\notebooks\casting\dataset\test\images\cast_ok_0_3812_jpeg.rf.660e6e7c8cec7667c7a5418cae70b1e5.jpg
Elapsed time = 8.994671106338501
[('no_defect', 99.99972581863403)]
[{'class': 'no_defect', 'x1': 14, 'x2': 619, 'y1': 67, 'y2': 623}]
[0.9564001916949371]
9.0  0.0  0.0  0.0  0.0  0.0  
0.0  30.0  10.0  0.0  0.0  0.0  
0.0  2.0  16.0  0.0  0.0  0.0  
0.0  9.0  0.0  24.0  0.0  0.0  
0.0  0.0  2.0  1.0  15.0  0.0  
0.0  0.0  0.0  0.0  0.0  0.0  
c:\Users\luizh\Desktop\estagio\notebooks\casting\dataset\test\images\cast_ok_0_4010_jpeg.rf.6af5fb012698476a0a4a062cf1a25422.jpg
Elapsed time = 8.325993537902832
[('no_defect', 99.9998927116394)]
[{'class': 'no_defect', 'x1': 24, 'x2': 591, 'y1': 46, 'y2': 597}]
[0.9720622855005245]
9.0  0.0  0.0  0.0  0.0  0.0  
0.0  30.0  10.0  0.0  0.0  0.0  
0.0  2.0  16.0  0.0  0.0  0.0  
0.0  9.0  0.0  24.0  0.0  0.0  
0.0  0.0  2.0  1.0  16.0  0.0  
0.0  0.0  0.0  0.0  0.0  0.0  
c:\Users\luizh\Desktop\estagio\notebooks\casting\dataset\test\images\cast_ok_0_4038_jpeg.rf.38b05e5f0993ef9ec96e984045353975.jpg
Elapsed time = 8.439701080322266
[('no_defect', 99.9995231628418)]
[{'class': 'no_defect', 'x1': 43, 'x2': 599, 'y1': 55, 'y2': 618}]
[0.9534014598510844]
9.0  0.0  0.0  0.0  0.0  0.0  
0.0  30.0  10.0  0.0  0.0  0.0  
0.0  2.0  16.0  0.0  0.0  0.0  
0.0  9.0  0.0  24.0  0.0  0.0  
0.0  0.0  2.0  1.0  17.0  0.0  
0.0  0.0  0.0  0.0  0.0  0.0  
c:\Users\luizh\Desktop\estagio\notebooks\casting\dataset\test\images\cast_ok_0_4691_jpeg.rf.eb2b8b7d8d79fbd20818396b53a973e3.jpg
Elapsed time = 9.628989696502686
[('no_defect', 99.99984502792358)]
[{'class': 'no_defect', 'x1': 106, 'x2': 565, 'y1': 131, 'y2': 586}]
[0.9453689009524305]
9.0  0.0  0.0  0.0  0.0  0.0  
0.0  30.0  10.0  0.0  0.0  0.0  
0.0  2.0  16.0  0.0  0.0  0.0  
0.0  9.0  0.0  24.0  0.0  0.0  
0.0  0.0  2.0  1.0  18.0  0.0  
0.0  0.0  0.0  0.0  0.0  0.0  
c:\Users\luizh\Desktop\estagio\notebooks\casting\dataset\test\images\cast_ok_0_4736_jpeg.rf.92dc65a568fb52af2a495ae974545445.jpg
Elapsed time = 8.345579624176025
[('no_defect', 99.99960660934448)]
[{'class': 'no_defect', 'x1': 108, 'x2': 586, 'y1': 67, 'y2': 495}]
[0.9392917993881986]
9.0  0.0  0.0  0.0  0.0  0.0  
0.0  30.0  10.0  0.0  0.0  0.0  
0.0  2.0  16.0  0.0  0.0  0.0  
0.0  9.0  0.0  24.0  0.0  0.0  
0.0  0.0  2.0  1.0  19.0  0.0  
0.0  0.0  0.0  0.0  0.0  0.0  
c:\Users\luizh\Desktop\estagio\notebooks\casting\dataset\test\images\cast_ok_0_5536_jpeg.rf.7e68844f3ba03544c3cafc7a35686833.jpg
Elapsed time = 8.417396545410156
[('no_defect', 99.99979734420776)]
[{'class': 'no_defect', 'x1': 53, 'x2': 608, 'y1': 15, 'y2': 622}]
[0.9862037620743144]
9.0  0.0  0.0  0.0  0.0  0.0  
0.0  30.0  10.0  0.0  0.0  0.0  
0.0  2.0  16.0  0.0  0.0  0.0  
0.0  9.0  0.0  24.0  0.0  0.0  
0.0  0.0  2.0  1.0  20.0  0.0  
0.0  0.0  0.0  0.0  0.0  0.0  
c:\Users\luizh\Desktop\estagio\notebooks\casting\dataset\test\images\cast_ok_0_5852_jpeg.rf.f15747d290e0e4427462a89beaf37f39.jpg
Elapsed time = 8.372148036956787
[('no_defect', 99.99967813491821)]
[{'class': 'no_defect', 'x1': 51, 'x2': 577, 'y1': 71, 'y2': 578}]
[0.975107854924639]
9.0  0.0  0.0  0.0  0.0  0.0  
0.0  30.0  10.0  0.0  0.0  0.0  
0.0  2.0  16.0  0.0  0.0  0.0  
0.0  9.0  0.0  24.0  0.0  0.0  
0.0  0.0  2.0  1.0  21.0  0.0  
0.0  0.0  0.0  0.0  0.0  0.0  
c:\Users\luizh\Desktop\estagio\notebooks\casting\dataset\test\images\cast_ok_0_6034_jpeg.rf.92cfa087d282e18e51166bc04d155e18.jpg
Elapsed time = 8.975355386734009
[('no_defect', 99.94495511054993)]
[{'class': 'no_defect', 'x1': 46, 'x2': 578, 'y1': 44, 'y2': 584}]
[0.9708546023348879]
9.0  0.0  0.0  0.0  0.0  0.0  
0.0  30.0  10.0  0.0  0.0  0.0  
0.0  2.0  16.0  0.0  0.0  0.0  
0.0  9.0  0.0  24.0  0.0  0.0  
0.0  0.0  2.0  1.0  22.0  0.0  
0.0  0.0  0.0  0.0  0.0  0.0  
c:\Users\luizh\Desktop\estagio\notebooks\casting\dataset\test\images\cast_ok_0_6193_jpeg.rf.88eb6e09904a3639796518ab8e3edf5b.jpg
Elapsed time = 9.136570692062378
[('no_defect', 99.81861710548401)]
[{'class': 'no_defect', 'x1': 56, 'x2': 605, 'y1': 52, 'y2': 591}]
[0.9713465073497527]
9.0  0.0  0.0  0.0  0.0  0.0  
0.0  30.0  10.0  0.0  0.0  0.0  
0.0  2.0  16.0  0.0  0.0  0.0  
0.0  9.0  0.0  24.0  0.0  0.0  
0.0  0.0  2.0  1.0  23.0  0.0  
0.0  0.0  0.0  0.0  0.0  0.0  
c:\Users\luizh\Desktop\estagio\notebooks\casting\dataset\test\images\cast_ok_0_6267_jpeg.rf.68f4c12c5811daa0ec6648579a86ddbf.jpg
Elapsed time = 8.828855991363525
[('no_defect', 99.54944849014282)]
[{'class': 'no_defect', 'x1': 44, 'x2': 609, 'y1': 37, 'y2': 599}]
[0.970249430272]
9.0  0.0  0.0  0.0  0.0  0.0  
0.0  30.0  10.0  0.0  0.0  0.0  
0.0  2.0  16.0  0.0  0.0  0.0  
0.0  9.0  0.0  24.0  0.0  0.0  
0.0  0.0  2.0  1.0  24.0  0.0  
0.0  0.0  0.0  0.0  0.0  0.0  
c:\Users\luizh\Desktop\estagio\notebooks\casting\dataset\test\images\cast_ok_0_6329_jpeg.rf.1e2122b7f7286186df950ca041ee61f3.jpg
Elapsed time = 9.614847660064697
[('no_defect', 99.99939203262329)]
[{'class': 'no_defect', 'x1': 49, 'x2': 605, 'y1': 52, 'y2': 569}]
[0.9682028218419869]
9.0  0.0  0.0  0.0  0.0  0.0  
0.0  30.0  10.0  0.0  0.0  0.0  
0.0  2.0  16.0  0.0  0.0  0.0  
0.0  9.0  0.0  24.0  0.0  0.0  
0.0  0.0  2.0  1.0  25.0  0.0  
0.0  0.0  0.0  0.0  0.0  0.0  
c:\Users\luizh\Desktop\estagio\notebooks\casting\dataset\test\images\cast_ok_0_6332_jpeg.rf.3296208f221cf66f23f541eb0889ad93.jpg
Elapsed time = 8.698189735412598
[('no_defect', 99.99867677688599)]
[{'class': 'no_defect', 'x1': 10, 'x2': 609, 'y1': 31, 'y2': 593}]
[0.9847967252627903]
9.0  0.0  0.0  0.0  0.0  0.0  
0.0  30.0  10.0  0.0  0.0  0.0  
0.0  2.0  16.0  0.0  0.0  0.0  
0.0  9.0  0.0  24.0  0.0  0.0  
0.0  0.0  2.0  1.0  26.0  0.0  
0.0  0.0  0.0  0.0  0.0  0.0  
c:\Users\luizh\Desktop\estagio\notebooks\casting\dataset\test\images\cast_ok_0_6432_jpeg.rf.10be499a5e91b2beac6b4123924a15bc.jpg
Elapsed time = 8.909980058670044
[('no_defect', 99.14107322692871), ('unpolished', 83.70171785354614)]
[{'class': 'no_defect', 'x1': 67, 'x2': 552, 'y1': 57, 'y2': 537}]
[0.950015529553991]
9.0  0.0  0.0  0.0  0.0  0.0  
0.0  30.0  10.0  0.0  0.0  0.0  
0.0  2.0  16.0  0.0  0.0  0.0  
0.0  9.0  0.0  24.0  0.0  0.0  
0.0  0.0  2.0  1.0  27.0  0.0  
0.0  0.0  0.0  0.0  0.0  0.0  
c:\Users\luizh\Desktop\estagio\notebooks\casting\dataset\test\images\cast_ok_0_6471_jpeg.rf.a8d98227579e67d2004004e0602665f9.jpg
Elapsed time = 8.244506120681763
[('no_defect', 99.99978542327881)]
[{'class': 'no_defect', 'x1': 1, 'x2': 604, 'y1': 51, 'y2': 576}]
[0.9608555506963843]
9.0  0.0  0.0  0.0  0.0  0.0  
0.0  30.0  10.0  0.0  0.0  0.0  
0.0  2.0  16.0  0.0  0.0  0.0  
0.0  9.0  0.0  24.0  0.0  0.0  
0.0  0.0  2.0  1.0  28.0  0.0  
0.0  0.0  0.0  0.0  0.0  0.0  
c:\Users\luizh\Desktop\estagio\notebooks\casting\dataset\test\images\cast_ok_0_660_jpeg.rf.abed494595b2dde8daffdfd9f7753eca.jpg
Elapsed time = 8.5461905002594
[('no_defect', 99.93199110031128)]
[{'class': 'no_defect', 'x1': 39, 'x2': 591, 'y1': 70, 'y2': 599}]
[0.9619421520679368]
9.0  0.0  0.0  0.0  0.0  0.0  
0.0  30.0  10.0  0.0  0.0  0.0  
0.0  2.0  16.0  0.0  0.0  0.0  
0.0  9.0  0.0  24.0  0.0  0.0  
0.0  0.0  2.0  1.0  29.0  0.0  
0.0  0.0  0.0  0.0  0.0  0.0  
c:\Users\luizh\Desktop\estagio\notebooks\casting\dataset\test\images\cast_ok_0_6644_jpeg.rf.1077eb3142675a81716971242ec2e851.jpg
Elapsed time = 8.26517128944397
[('no_defect', 99.99972581863403)]
[{'class': 'no_defect', 'x1': 44, 'x2': 620, 'y1': 57, 'y2': 584}]
[0.9587416193883486]
9.0  0.0  0.0  0.0  0.0  0.0  
0.0  30.0  10.0  0.0  0.0  0.0  
0.0  2.0  16.0  0.0  0.0  0.0  
0.0  9.0  0.0  24.0  0.0  0.0  
0.0  0.0  2.0  1.0  30.0  0.0  
0.0  0.0  0.0  0.0  0.0  0.0  
c:\Users\luizh\Desktop\estagio\notebooks\casting\dataset\test\images\cast_ok_0_6738_jpeg.rf.c6131d8cab2ec0e64b8e19461579b4f4.jpg
Elapsed time = 8.529184103012085
[('no_defect', 99.9984622001648)]
[{'class': 'no_defect', 'x1': 113, 'x2': 574, 'y1': 142, 'y2': 569}]
[0.9681011635782422]
9.0  0.0  0.0  0.0  0.0  0.0  
0.0  30.0  10.0  0.0  0.0  0.0  
0.0  2.0  16.0  0.0  0.0  0.0  
0.0  9.0  0.0  24.0  0.0  0.0  
0.0  0.0  2.0  1.0  31.0  0.0  
0.0  0.0  0.0  0.0  0.0  0.0  
c:\Users\luizh\Desktop\estagio\notebooks\casting\dataset\test\images\cast_ok_0_6788_jpeg.rf.2551661902308b076010c72890f086b3.jpg
Elapsed time = 8.411309480667114
[('no_defect', 99.99933242797852)]
[{'class': 'no_defect', 'x1': 38, 'x2': 591, 'y1': 66, 'y2': 582}]
[0.9723898247782277]
9.0  0.0  0.0  0.0  0.0  0.0  
0.0  30.0  10.0  0.0  0.0  0.0  
0.0  2.0  16.0  0.0  0.0  0.0  
0.0  9.0  0.0  24.0  0.0  0.0  
0.0  0.0  2.0  1.0  32.0  0.0  
0.0  0.0  0.0  0.0  0.0  0.0  
c:\Users\luizh\Desktop\estagio\notebooks\casting\dataset\test\images\cast_ok_0_7005_jpeg.rf.5ae93417546c45bf0fb27f4c2f9ee878.jpg
Elapsed time = 8.29157304763794
[('no_defect', 99.99876022338867)]
[{'class': 'no_defect', 'x1': 61, 'x2': 579, 'y1': 23, 'y2': 638}]
[0.9502368953105282]
9.0  0.0  0.0  0.0  0.0  0.0  
0.0  30.0  10.0  0.0  0.0  0.0  
0.0  2.0  16.0  0.0  0.0  0.0  
0.0  9.0  0.0  24.0  0.0  0.0  
0.0  0.0  2.0  1.0  33.0  0.0  
0.0  0.0  0.0  0.0  0.0  0.0  
c:\Users\luizh\Desktop\estagio\notebooks\casting\dataset\test\images\cast_ok_0_7206_jpeg.rf.aa003a5e6668efbf4de1507864759a74.jpg
Elapsed time = 8.415425062179565
[('no_defect', 99.99877214431763)]
[{'class': 'no_defect', 'x1': 25, 'x2': 618, 'y1': 24, 'y2': 574}]
[0.9610281181949458]
9.0  0.0  0.0  0.0  0.0  0.0  
0.0  30.0  10.0  0.0  0.0  0.0  
0.0  2.0  16.0  0.0  0.0  0.0  
0.0  9.0  0.0  24.0  0.0  0.0  
0.0  0.0  2.0  1.0  34.0  0.0  
0.0  0.0  0.0  0.0  0.0  0.0  
c:\Users\luizh\Desktop\estagio\notebooks\casting\dataset\test\images\cast_ok_0_7256_jpeg.rf.fc46d5e85a4d178949828779de3e0e36.jpg
Elapsed time = 8.472568035125732
[('no_defect', 99.99959468841553)]
[{'class': 'no_defect', 'x1': 31, 'x2': 631, 'y1': 31, 'y2': 629}]
[0.9738553475674108]
9.0  0.0  0.0  0.0  0.0  0.0  
0.0  30.0  10.0  0.0  0.0  0.0  
0.0  2.0  16.0  0.0  0.0  0.0  
0.0  9.0  0.0  24.0  0.0  0.0  
0.0  0.0  2.0  1.0  35.0  0.0  
0.0  0.0  0.0  0.0  0.0  0.0  
c:\Users\luizh\Desktop\estagio\notebooks\casting\dataset\test\images\cast_ok_0_7355_jpeg.rf.aa3cada8b603a64e2e365954a416f694.jpg
Elapsed time = 8.45796513557434
[('no_defect', 99.81367588043213)]
[{'class': 'no_defect', 'x1': 67, 'x2': 597, 'y1': 60, 'y2': 601}]
[0.9548876721121035]
9.0  0.0  0.0  0.0  0.0  0.0  
0.0  30.0  10.0  0.0  0.0  0.0  
0.0  2.0  16.0  0.0  0.0  0.0  
0.0  9.0  0.0  24.0  0.0  0.0  
0.0  0.0  2.0  1.0  36.0  0.0  
0.0  0.0  0.0  0.0  0.0  0.0  
c:\Users\luizh\Desktop\estagio\notebooks\casting\dataset\test\images\cast_ok_0_7511_jpeg.rf.de4314d6d116835a0c66e5caa3219a0d.jpg
Elapsed time = 8.437429189682007
[('unpolished', 99.99281167984009), ('crack', 96.2519884109497)]
[{'class': 'unpolished', 'x1': 48, 'x2': 570, 'y1': 38, 'y2': 633}]
[0.9565455809088874]
9.0  0.0  0.0  0.0  0.0  0.0  
0.0  30.0  10.0  0.0  0.0  0.0  
0.0  2.0  16.0  0.0  0.0  0.0  
0.0  9.0  0.0  25.0  0.0  0.0  
0.0  0.0  2.0  1.0  36.0  0.0  
0.0  0.0  0.0  0.0  0.0  0.0  
c:\Users\luizh\Desktop\estagio\notebooks\casting\dataset\test\images\cast_ok_0_8113_jpeg.rf.ab8767e81686506103fd7fcf2d5c48a2.jpg
Elapsed time = 8.976366996765137
[('no_defect', 99.9993085861206)]
[{'class': 'no_defect', 'x1': 48, 'x2': 618, 'y1': 26, 'y2': 591}]
[0.9774526044512625]
9.0  0.0  0.0  0.0  0.0  0.0  
0.0  30.0  10.0  0.0  0.0  0.0  
0.0  2.0  16.0  0.0  0.0  0.0  
0.0  9.0  0.0  25.0  0.0  0.0  
0.0  0.0  2.0  1.0  37.0  0.0  
0.0  0.0  0.0  0.0  0.0  0.0  
c:\Users\luizh\Desktop\estagio\notebooks\casting\dataset\test\images\cast_ok_0_8460_jpeg.rf.f3840051830c33c492ea521cfecb9ef8.jpg
Elapsed time = 9.96132206916809
[('no_defect', 99.9996542930603)]
[{'class': 'no_defect', 'x1': 52, 'x2': 600, 'y1': 10, 'y2': 573}]
[0.9632299108803009]
9.0  0.0  0.0  0.0  0.0  0.0  
0.0  30.0  10.0  0.0  0.0  0.0  
0.0  2.0  16.0  0.0  0.0  0.0  
0.0  9.0  0.0  25.0  0.0  0.0  
0.0  0.0  2.0  1.0  38.0  0.0  
0.0  0.0  0.0  0.0  0.0  0.0  
c:\Users\luizh\Desktop\estagio\notebooks\casting\dataset\test\images\cast_ok_0_8476_jpeg.rf.9fc24cb040aa7898d61ff99138b1782a.jpg
Elapsed time = 8.65081262588501
[('no_defect', 99.76738095283508)]
[{'class': 'no_defect', 'x1': 58, 'x2': 593, 'y1': 60, 'y2': 596}]
[0.9583754128307503]
9.0  0.0  0.0  0.0  0.0  0.0  
0.0  30.0  10.0  0.0  0.0  0.0  
0.0  2.0  16.0  0.0  0.0  0.0  
0.0  9.0  0.0  25.0  0.0  0.0  
0.0  0.0  2.0  1.0  39.0  0.0  
0.0  0.0  0.0  0.0  0.0  0.0  
c:\Users\luizh\Desktop\estagio\notebooks\casting\dataset\test\images\cast_ok_0_8875_jpeg.rf.47d5c4565a5f18d84993f694904c2519.jpg
Elapsed time = 8.777033805847168
[('no_defect', 99.99929666519165)]
[{'class': 'no_defect', 'x1': 53, 'x2': 565, 'y1': 83, 'y2': 574}]
[0.9599217986278107]
9.0  0.0  0.0  0.0  0.0  0.0  
0.0  30.0  10.0  0.0  0.0  0.0  
0.0  2.0  16.0  0.0  0.0  0.0  
0.0  9.0  0.0  25.0  0.0  0.0  
0.0  0.0  2.0  1.0  40.0  0.0  
0.0  0.0  0.0  0.0  0.0  0.0  
c:\Users\luizh\Desktop\estagio\notebooks\casting\dataset\test\images\cast_ok_0_8888_jpeg.rf.410a01649dada6daadcd836c31f5c8f2.jpg
Elapsed time = 8.6289963722229
[('no_defect', 99.94586110115051)]
[{'class': 'no_defect', 'x1': 19, 'x2': 622, 'y1': 26, 'y2': 625}]
[0.9638474423301336]
9.0  0.0  0.0  0.0  0.0  0.0  
0.0  30.0  10.0  0.0  0.0  0.0  
0.0  2.0  16.0  0.0  0.0  0.0  
0.0  9.0  0.0  25.0  0.0  0.0  
0.0  0.0  2.0  1.0  41.0  0.0  
0.0  0.0  0.0  0.0  0.0  0.0  
c:\Users\luizh\Desktop\estagio\notebooks\casting\dataset\test\images\cast_ok_0_8931_jpeg.rf.8c465b686c663d7a39664cbcd6fa60f5.jpg
Elapsed time = 8.532318115234375
[('no_defect', 99.56373572349548)]
[{'class': 'no_defect', 'x1': 34, 'x2': 615, 'y1': 15, 'y2': 604}]
[0.9559615501831737]
9.0  0.0  0.0  0.0  0.0  0.0  
0.0  30.0  10.0  0.0  0.0  0.0  
0.0  2.0  16.0  0.0  0.0  0.0  
0.0  9.0  0.0  25.0  0.0  0.0  
0.0  0.0  2.0  1.0  42.0  0.0  
0.0  0.0  0.0  0.0  0.0  0.0  
c:\Users\luizh\Desktop\estagio\notebooks\casting\dataset\test\images\cast_ok_0_9393_jpeg.rf.77ec8a4df2991ce9460b1ffd91a5bd9b.jpg
Elapsed time = 8.818552732467651
[('no_defect', 99.99974966049194)]
[{'class': 'no_defect', 'x1': 55, 'x2': 573, 'y1': 75, 'y2': 577}]
[0.9581471936875285]
9.0  0.0  0.0  0.0  0.0  0.0  
0.0  30.0  10.0  0.0  0.0  0.0  
0.0  2.0  16.0  0.0  0.0  0.0  
0.0  9.0  0.0  25.0  0.0  0.0  
0.0  0.0  2.0  1.0  43.0  0.0  
0.0  0.0  0.0  0.0  0.0  0.0  
c:\Users\luizh\Desktop\estagio\notebooks\casting\dataset\test\images\cast_ok_0_9658_jpeg.rf.d4d995177ea04644238f588eef89cf58.jpg
Elapsed time = 8.584177017211914
[('no_defect', 99.99980926513672)]
[{'class': 'no_defect', 'x1': 7, 'x2': 609, 'y1': 34, 'y2': 586}]
[0.9727884773247883]
9.0  0.0  0.0  0.0  0.0  0.0  
0.0  30.0  10.0  0.0  0.0  0.0  
0.0  2.0  16.0  0.0  0.0  0.0  
0.0  9.0  0.0  25.0  0.0  0.0  
0.0  0.0  2.0  1.0  44.0  0.0  
0.0  0.0  0.0  0.0  0.0  0.0  
c:\Users\luizh\Desktop\estagio\notebooks\casting\dataset\test\images\cast_ok_0_9700_jpeg.rf.f93928f5590d395dc9db5ea93d8d2d82.jpg
Elapsed time = 8.537871837615967
[('no_defect', 99.92121458053589)]
[{'class': 'no_defect', 'x1': 38, 'x2': 572, 'y1': 52, 'y2': 587}]
[0.9653776492181911]
9.0  0.0  0.0  0.0  0.0  0.0  
0.0  30.0  10.0  0.0  0.0  0.0  
0.0  2.0  16.0  0.0  0.0  0.0  
0.0  9.0  0.0  25.0  0.0  0.0  
0.0  0.0  2.0  1.0  45.0  0.0  
0.0  0.0  0.0  0.0  0.0  0.0  
True Positives:  [ 9. 30. 16. 25. 45.  0.]
False Positives:  [ 0. 11. 12.  1.  0.  0.]
False Negatives:  [ 0. 10.  2.  9.  3.  0.]
True Negatives:  [140.  98. 119. 114. 101. 149.]
Precision:  [1.         0.73170732 0.57142857 0.96153846 1.                nan]
Recall:  [1.         0.75       0.88888889 0.73529412 0.9375            nan]
C:\Users\luizh\AppData\Local\Temp\ipykernel_25680\1764898296.py:175: RuntimeWarning: invalid value encountered in divide
  precision = tp / (tp + fp)
C:\Users\luizh\AppData\Local\Temp\ipykernel_25680\1764898296.py:176: RuntimeWarning: invalid value encountered in divide
  recall = tp / (tp + fn)